OSDN Git Service

throw error when transaction fail
[bytom/bytom-electron.git] / src / features / transactions / actions.js
1 import { chainClient } from 'utility/environment'
2 import { parseNonblankJSON } from 'utility/string'
3 import { push } from 'react-router-redux'
4 import { baseCreateActions, baseListActions } from 'features/shared/actions'
5
6 const type = 'transaction'
7
8 const list = baseListActions(type, {
9   defaultKey: 'id'
10 })
11 const form = baseCreateActions(type)
12
13 function preprocessTransaction(formParams) {
14   const copy = JSON.parse(JSON.stringify(formParams))
15   const builder = {
16     baseTransaction: copy.baseTransaction,
17     actions: copy.actions,
18   }
19
20   if (builder.baseTransaction == '') {
21     delete builder.baseTransaction
22   }
23
24   if (formParams.submitAction == 'generate') {
25     builder.ttl = '1h' // 1 hour
26   }
27
28   for (let i in builder.actions) {
29     let a = builder.actions[i]
30
31     const intFields = ['amount', 'position']
32     intFields.forEach(key => {
33       const value = a[key]
34       if (value) {
35         if ((parseInt(value)+'') == value) {
36           a[key] = parseInt(value)
37         } else {
38           throw new Error(`Action ${parseInt(i)+1} ${key} must be an integer.`)
39         }
40       }
41     })
42
43     try {
44       a.referenceData = parseNonblankJSON(a.referenceData)
45     } catch (err) {
46       throw new Error(`Action ${parseInt(i)+1} reference data should be valid JSON, or blank.`)
47     }
48
49     try {
50       a.receiver = parseNonblankJSON(a.receiver)
51     } catch (err) {
52       throw new Error(`Action ${parseInt(i)+1} receiver should be valid JSON.`)
53     }
54   }
55
56   return builder
57 }
58
59 form.submitForm = (formParams) => function(dispatch) {
60   const buildPromise = chainClient().transactions.build(builder => {
61     const processed = preprocessTransaction(formParams)
62
63     builder.actions = processed.actions.map(action => {
64       let result = {
65         address: action.address,
66         amount: action.amount,
67         account_id: action.accountId,
68         account_alias: action.accountAlias,
69         asset_id: action.assetId,
70         asset_alias: action.assetAlias,
71         type: action.type,
72       }
73       if (action.receiver) {
74         result.receiver = {
75           control_program: action.receiver.controlProgram,
76           expires_at: action.receiver.expiresAt
77         }
78       }
79       return result
80     })
81     if (processed.baseTransaction) {
82       builder.baseTransaction = processed.baseTransaction
83     }
84   })
85
86   if (formParams.submitAction == 'submit') {
87     return buildPromise
88       .then((resp) => {
89         if (resp.status === 'fail') {
90           throw new Error(resp.msg)
91         }
92
93         const tpl = resp.data
94         const password = (tpl.signing_instructions || []).map(() => '123456')
95         const client = chainClient()
96         const body = Object.assign({}, {password, 'transaction': tpl})
97         return client.connection.request('/sign-submit-transaction', body, true)
98       }).then(resp => {
99         if (resp.status === 'fail') {
100           throw new Error(resp.msg)
101         }
102
103         dispatch(form.created())
104         dispatch(push({
105           pathname: '/transactions'
106         }))
107       })
108   }
109 }
110
111 export default {
112   ...list,
113   ...form,
114 }