OSDN Git Service

support multi-sign in new transaction page
authorYongfeng LI <wliyongfeng@gmail.com>
Fri, 13 Apr 2018 09:11:28 +0000 (17:11 +0800)
committerYongfeng LI <wliyongfeng@gmail.com>
Fri, 13 Apr 2018 11:35:09 +0000 (19:35 +0800)
src/features/transactions/actions.js
src/features/transactions/components/GeneratedTxHex/GeneratedTxHex.jsx
src/features/transactions/components/New/New.jsx

index 84cfa9e..3977da5 100644 (file)
@@ -1,8 +1,8 @@
 import uuid from 'uuid'
-import { chainClient } from 'utility/environment'
-import { parseNonblankJSON } from 'utility/string'
-import { push } from 'react-router-redux'
-import { baseCreateActions, baseListActions } from 'features/shared/actions'
+import {chainClient} from 'utility/environment'
+import {parseNonblankJSON} from 'utility/string'
+import {push} from 'react-router-redux'
+import {baseCreateActions, baseListActions} from 'features/shared/actions'
 
 const type = 'transaction'
 
@@ -19,10 +19,29 @@ function preprocessTransaction(formParams) {
   }
 
   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 (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 (builder.baseTransaction == '') {
@@ -40,10 +59,10 @@ function preprocessTransaction(formParams) {
     intFields.forEach(key => {
       const value = a[key]
       if (value) {
-        if ((parseInt(value)+'') == value) {
+        if ((parseInt(value) + '') == value) {
           a[key] = parseInt(value)
         } else {
-          throw new Error(`Action ${parseInt(i)+1} ${key} must be an integer.`)
+          throw new Error(`Action ${parseInt(i) + 1} ${key} must be an integer.`)
         }
       }
     })
@@ -51,20 +70,20 @@ function preprocessTransaction(formParams) {
     try {
       a.referenceData = parseNonblankJSON(a.referenceData)
     } catch (err) {
-      throw new Error(`Action ${parseInt(i)+1} reference data should be valid JSON, or blank.`)
+      throw new Error(`Action ${parseInt(i) + 1} reference data should be valid JSON, or blank.`)
     }
 
     try {
       a.receiver = parseNonblankJSON(a.receiver)
     } catch (err) {
-      throw new Error(`Action ${parseInt(i)+1} receiver should be valid JSON.`)
+      throw new Error(`Action ${parseInt(i) + 1} receiver should be valid JSON.`)
     }
   }
 
   return builder
 }
 
-form.submitForm = (formParams) => function(dispatch) {
+form.submitForm = (formParams) => function (dispatch) {
   const buildPromise = chainClient().transactions.build(builder => {
     const processed = preprocessTransaction(formParams)
 
@@ -91,6 +110,28 @@ form.submitForm = (formParams) => function(dispatch) {
     }
   })
 
+  const dealSignSubmitResp = resp => {
+    if (resp.status === 'fail') {
+      throw new Error(resp.msg)
+    }
+
+    dispatch(form.created())
+    dispatch(push({
+      pathname: '/transactions',
+      state: {
+        preserveFlash: true
+      }
+    }))
+  }
+
+  if (formParams.state.showAdvanceTx && formParams.state.showAdvanced && formParams.baseTransaction) {
+    const transaction = JSON.parse(formParams.baseTransaction)
+    return chainClient().connection.request('/sign-submit-transaction', {
+      password: formParams.password,
+      transaction
+    }, true).then(dealSignSubmitResp)
+  }
+
   if (formParams.submitAction == 'submit') {
     return buildPromise
       .then((resp) => {
@@ -100,19 +141,7 @@ form.submitForm = (formParams) => function(dispatch) {
 
         const body = Object.assign({}, {password: formParams.password, 'transaction': resp.data})
         return chainClient().connection.request('/sign-submit-transaction', body, true)
-      }).then(resp => {
-        if (resp.status === 'fail') {
-          throw new Error(resp.msg)
-        }
-
-        dispatch(form.created())
-        dispatch(push({
-          pathname: '/transactions',
-          state: {
-            preserveFlash: true
-          }
-        }))
-      })
+      }).then(dealSignSubmitResp)
   }
 
   // submitAction == 'generate'
@@ -132,7 +161,7 @@ form.submitForm = (formParams) => function(dispatch) {
       type: 'GENERATED_TX_HEX',
       generated: {
         id: id,
-        hex: resp.data.transaction.raw_transaction,
+        hex: JSON.stringify(resp.data.transaction),
       },
     })
     dispatch(push(`/transactions/generated/${id}`))
index 7b684c5..b53a020 100644 (file)
@@ -14,7 +14,7 @@ class Generated extends React.Component {
 
         <PageContent>
           <div className={styles.main}>
-            <p>Use the following hex string as the base transaction for a future transaction:</p>
+            <p>Use the following JSON string as the transaction to sign by another account:</p>
 
             <button
               className='btn btn-primary'
index 0ffcad0..28fffbb 100644 (file)
@@ -115,7 +115,7 @@ class Form extends React.Component {
 
   submitWithValidation(data) {
     return new Promise((resolve, reject) => {
-      this.props.submitForm(data)
+      this.props.submitForm(Object.assign({}, data, {state: this.state}))
         .catch((err) => {
           const response = {}
 
@@ -144,8 +144,9 @@ class Form extends React.Component {
     const lang = this.props.lang
 
     let submitLabel = lang === 'zh' ? '提交交易' : 'Submit transaction'
-    if (submitAction.value == 'generate') {
-      submitLabel = lang === 'zh' ? '生成交易hex' : 'Generate transaction hex'
+    const hasBaseTransaction = ((baseTransaction.value || '').trim()).length > 0
+    if (submitAction.value == 'generate' && !hasBaseTransaction) {
+      submitLabel = lang === 'zh' ? '生成交易JSON' : 'Generate transaction JSON'
     }
 
     const gasOnChange = event => {
@@ -305,7 +306,7 @@ class Form extends React.Component {
         {this.state.showAdvanceTx && this.state.showAdvanced && <FormSection title={ lang === 'zh' ? '高级选项' :'Advanced Options' }>
           <div>
             <TextField
-              title='Base transaction'
+              title='To sign transaction'
               placeholder='Paste transaction hex here...'
               fieldProps={baseTransaction}
               autoFocus={true} />
@@ -327,14 +328,12 @@ class Form extends React.Component {
               <tr>
                 <td><input id='submit_action_generate' type='radio' {...submitAction} value='generate' checked={submitAction.value == 'generate'} /></td>
                 <td>
-                  <label htmlFor='submit_action_generate'>{ lang === 'zh' ? '允许更多actions' : 'Allow additional actions' }</label>
+                  <label htmlFor='submit_action_generate'>{ lang === 'zh' ? '需要更多签名' : 'Need more signature' }</label>
                   <br />
                   <label htmlFor='submit_action_generate' className={styles.submitDescription}>
-                    { lang === 'zh' ? '这些actions将通过密钥签名然后作为一个交易 hex 字符串返回, 字符串可以用做base transaction于 multi-party swap。' +
-                      '此次交易将持续有效一个小时。' :
-                      'These actions will be signed by the MockHSM and returned as a transaction hex string, ' +
-                      'which should be used as the base transaction in a multi-party swap. This transaction ' +
-                      'will be valid for one hour.'  }
+                    {lang === 'zh' ? '这些actions将通过密钥签名然后作为一个交易 JSON 字符串返回, 字符串可以用做To sign transaction于 multi-sign spend。' :
+                      'These actions will be signed by the Key and returned as a transaction JSON string, ' +
+                      'which should be used as the to sign transaction in a multi-sign spend.'}
                   </label>
                 </td>
               </tr>
@@ -358,9 +357,13 @@ const validate = values => {
   const errors = {actions: {}, normalTransaction:{gas:{}}}
 
   // Base transaction
-  let baseTx = values.baseTransaction || ''
-  if (baseTx.trim().match(/[^0-9a-fA-F]/)) {
-    errors.baseTransaction = 'Base transaction must be a hex string.'
+  let baseTx = (values.baseTransaction || '').trim()
+  try {
+    JSON.parse(baseTx)
+  } catch (e) {
+    if (baseTx && e) {
+      errors.baseTransaction = 'To sign transaction must be a JSON string.'
+    }
   }
 
   // Actions