OSDN Git Service

correct transaction create data path
[bytom/bytom-electron.git] / src / features / transactions / actions.js
1 import uuid from 'uuid'
2 import { chainClient, chainSigner } from 'utility/environment'
3 import { parseNonblankJSON } from 'utility/string'
4 import { push } from 'react-router-redux'
5 import { baseCreateActions, baseListActions } from 'features/shared/actions'
6
7 const type = 'transaction'
8
9 const list = baseListActions(type, {
10   defaultKey: 'id'
11 })
12 const form = baseCreateActions(type)
13
14 function preprocessTransaction(formParams) {
15   const copy = JSON.parse(JSON.stringify(formParams))
16   const builder = {
17     baseTransaction: copy.baseTransaction,
18     actions: copy.actions,
19   }
20
21   if (builder.baseTransaction == '') {
22     delete builder.baseTransaction
23   }
24
25   if (formParams.submitAction == 'generate') {
26     builder.ttl = '1h' // 1 hour
27   }
28
29   for (let i in builder.actions) {
30     let a = builder.actions[i]
31
32     const intFields = ['amount', 'position']
33     intFields.forEach(key => {
34       const value = a[key]
35       if (value) {
36         if ((parseInt(value)+'') == value) {
37           a[key] = parseInt(value)
38         } else {
39           throw new Error(`Action ${parseInt(i)+1} ${key} must be an integer.`)
40         }
41       }
42     })
43
44     try {
45       a.referenceData = parseNonblankJSON(a.referenceData)
46     } catch (err) {
47       throw new Error(`Action ${parseInt(i)+1} reference data should be valid JSON, or blank.`)
48     }
49
50     try {
51       a.receiver = parseNonblankJSON(a.receiver)
52     } catch (err) {
53       throw new Error(`Action ${parseInt(i)+1} receiver should be valid JSON.`)
54     }
55   }
56
57   return builder
58 }
59
60 function getTemplateXpubs(tpl) {
61   const xpubs = []
62   tpl['signing_instructions'].forEach((instruction) => {
63     instruction['witness_components'].forEach((component) => {
64       component.keys.forEach((key) => {
65         xpubs.push(key.xpub)
66       })
67     })
68   })
69   return xpubs
70 }
71
72 form.submitForm = (formParams) => function(dispatch) {
73   const buildPromise = chainClient().transactions.build(builder => {
74     const processed = preprocessTransaction(formParams)
75
76     builder.actions = processed.actions.map(action => {
77       return {
78         amount: action.amount,
79         account_id: action.accountId,
80         account_alias: action.accountAlias,
81         asset_id: action.assetId,
82         asset_alias: action.assetAlias,
83         type: action.type
84       }
85     })
86     builder.actions.push({
87       account_id: '08ALDMJ900A02',
88       amount:20000000,
89       asset_id:'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
90       type:'spend_account'})
91     if (processed.baseTransaction) {
92       builder.baseTransaction = processed.baseTransaction
93     }
94   })
95
96   if (formParams.submitAction == 'submit') {
97     return buildPromise
98       .then(({data: tpl}) => {
99         const client = chainClient()
100         const body = Object.assign({}, {Auth: '123456', 'transaction': tpl})
101         return client.connection.request('/sign-submit-transaction', body, true)
102       }).then(resp => {
103         if (resp.status === 'fail') {
104           // TODO: deal with failure
105           return
106         }
107
108         dispatch(form.created())
109         dispatch(push({
110           pathname: `/transactions/${resp.data.txid}`,
111           state: {
112             preserveFlash: true
113           }
114         }))
115       })
116   }
117
118   // submitAction == 'generate'
119   return buildPromise
120     .then(tpl => {
121       const data = tpl.data
122       const signer = chainSigner()
123
124       getTemplateXpubs(data).forEach(key => {
125         signer.addKey(key, chainClient().mockHsm.signerConnection)
126       })
127
128       return signer.sign({...data, allowAdditionalActions: true})
129     })
130     .then(signed => {
131       const id = uuid.v4()
132       dispatch({
133         type: 'GENERATED_TX_HEX',
134         generated: {
135           id: id,
136           hex: signed.rawTransaction,
137         },
138       })
139       dispatch(push(`/transactions/generated/${id}`))
140     })
141 }
142
143 export default {
144   ...list,
145   ...form,
146 }