1 import uuid from 'uuid'
2 import { chainClient } from 'utility/environment'
3 import { parseNonblankJSON } from 'utility/string'
4 import { push } from 'react-router-redux'
5 import { baseCreateActions, baseListActions } from 'features/shared/actions'
7 const type = 'transaction'
9 const list = baseListActions(type, {
12 const form = baseCreateActions(type)
14 function preprocessTransaction(formParams) {
15 const copy = JSON.parse(JSON.stringify(formParams))
17 baseTransaction: copy.baseTransaction,
18 actions: copy.actions,
21 const normalT = formParams.normalTransaction
22 if( builder.actions.length == 0){
23 builder.actions.push({accountAlias: normalT.accountAlias, accountId: normalT.accountId, assetAlias: 'btm', amount: Number(normalT.gas.price), type: 'spend_account'})
24 builder.actions.push({accountAlias: normalT.accountAlias, accountId: normalT.accountId, assetAlias: normalT.assetAlias, assetId: normalT.assetId, amount: normalT.amount, type: 'spend_account'})
25 builder.actions.push({address: normalT.address, assetAlias: normalT.assetAlias, assetId: normalT.assetId, amount: normalT.amount, type: 'control_address'})
28 if (builder.baseTransaction == '') {
29 delete builder.baseTransaction
32 if (formParams.submitAction == 'generate') {
33 builder.ttl = '1h' // 1 hour
36 for (let i in builder.actions) {
37 let a = builder.actions[i]
39 const intFields = ['amount', 'position']
40 intFields.forEach(key => {
43 if ((parseInt(value)+'') == value) {
44 a[key] = parseInt(value)
46 throw new Error(`Action ${parseInt(i)+1} ${key} must be an integer.`)
52 a.referenceData = parseNonblankJSON(a.referenceData)
54 throw new Error(`Action ${parseInt(i)+1} reference data should be valid JSON, or blank.`)
58 a.receiver = parseNonblankJSON(a.receiver)
60 throw new Error(`Action ${parseInt(i)+1} receiver should be valid JSON.`)
67 form.submitForm = (formParams) => function(dispatch) {
68 const buildPromise = chainClient().transactions.build(builder => {
69 const processed = preprocessTransaction(formParams)
71 builder.actions = processed.actions.map(action => {
73 address: action.address,
74 amount: action.amount,
75 account_id: action.accountId,
76 account_alias: action.accountAlias,
77 asset_id: action.assetId,
78 asset_alias: action.assetAlias,
81 if (action.receiver) {
83 control_program: action.receiver.controlProgram,
84 expires_at: action.receiver.expiresAt
89 if (processed.baseTransaction) {
90 builder.baseTransaction = processed.baseTransaction
94 if (formParams.submitAction == 'submit') {
97 if (resp.status === 'fail') {
98 throw new Error(resp.msg)
101 const tpl = resp.data
102 const password = (tpl.signing_instructions || []).map(() => '123456')
103 const client = chainClient()
104 const body = Object.assign({}, {password, 'transaction': tpl})
105 return client.connection.request('/sign-submit-transaction', body, true)
107 if (resp.status === 'fail') {
108 throw new Error(resp.msg)
111 dispatch(form.created())
113 pathname: '/transactions'
118 // submitAction == 'generate'
119 return buildPromise.then(resp => {
120 if (resp.status === 'fail') {
121 throw new Error(resp.msg)
124 const tpl = resp.data
125 const password = (tpl.signing_instructions || []).map(() => '123456')
126 const client = chainClient()
127 const body = Object.assign({}, {password, 'transaction': tpl})
128 return client.connection.request('/sign-transaction', body, true)
130 if (resp.status === 'fail') {
131 throw new Error(resp.msg)
135 type: 'GENERATED_TX_HEX',
138 hex: resp.data.raw_transaction,
141 dispatch(push(`/transactions/generated/${id}`))