OSDN Git Service

update cross chain v3 api
[bytom/Byone.git] / src / views / sendTransaction / crossChainTransaction.vue
1 <style lang="" scoped>
2 .header {
3   display: flex;
4 }
5 .header p{
6   text-align: center;
7   width: 270px;
8   padding-top: 17px;
9 }
10 .transferType {
11   /*width: 280px;*/
12   /*height: 40px;*/
13     margin: 20px;
14   display: flex;
15 }
16
17 .transferType input[type=radio] {
18   position: absolute;
19   visibility: hidden;
20 }
21
22 .transferType input[type="radio"]:checked+label{
23   color:white;
24   background: linear-gradient(90deg, #227AF1 100%, #035BD4 0%);;
25 }
26 .transferType input[type="radio"]:checked+label .cross-icon{
27   background-image: url('../../assets/img/icon/crosschain-toV.svg');
28 }
29
30 .transferType div:last-child input[type="radio"]:checked+label{
31   color:white;
32   background: linear-gradient(91deg, #4B4B4B 0.27%, #1C1C1C 99.68%);
33 }
34
35 .transferType div:last-child input[type="radio"]:checked+label .cross-icon{
36   background-image: url('../../assets/img/icon/crosschain-toB.svg');
37 }
38
39 .transferType div:last-child .choice{
40   border-radius: 0px 40px 40px 0px;
41
42 }
43 .choice {
44   cursor: pointer;
45   padding: 10px;
46   font-size: 12px;
47   white-space: pre-wrap;
48   display: flex;
49   width: 140px;
50   background: rgba(0, 0, 0, 0.04);
51   border-radius: 40px 0px 0px 40px;
52 }
53
54 .choice:hover {
55      background-color: #f7f7f7;
56    }
57
58 .form-container{
59   margin: 20px;
60 }
61 .form {
62     margin-bottom: 20px;
63     padding: 10px 15px;
64     border-radius:4px;
65 }
66 .form-container .btn{
67     height: 48px;
68     bottom: 20px;
69     position: absolute;
70     width: 320px;
71 }
72   .small{
73     font-size: 12px;
74   }
75 .wallet{
76   width: 40px;
77   height: 40px;
78   background: rgba(255,255,255,0.1);
79   border-radius: 50%;
80   color: white;
81   margin-right: 20px;
82   line-height: 40px;
83   text-align: center;
84 }
85
86 .asset-option{
87   font-size: 15px;
88   text-transform: uppercase;
89 }
90
91 .asset-option  .asset-id{
92   font-size: 13px;
93 }
94
95 .v-select{
96   height: 50px;
97   width: 100%;
98   background: rgba(247,247,247,1);
99   font-size: 14px;
100   margin: auto;
101   border-bottom: 1px solid #E0E0E0;
102 }
103
104   .cross-icon{
105     background-image: url('../../assets/img/icon/crosschain-default.svg');
106     height:40px;
107     width:40px;
108     margin:auto 12px;
109   }
110   .separator{
111     height: 12px;
112   }
113 </style>
114
115 <template>
116     <div class="warp-chlid bg-white">
117         <section class="header bg-header">
118             <i class="iconfont icon-back" @click="close"></i>
119             <p>{{ $t('crossChain.title') }}</p>
120         </section>
121
122         <section class="transferType">
123           <div>
124             <input type="radio" id="typeChoice1"
125                    value="toVapor" v-model="transaction.type">
126             <label class="choice" for="typeChoice1"> <div class="cross-icon"></div><div>{{$t('crossChain.toVapor')}}</div></label>
127
128           </div>
129           <div>
130             <input type="radio" id="typeChoice2"
131                    value="toBytom" v-model="transaction.type">
132             <label class="choice" for="typeChoice2"><div class="cross-icon"></div><div>{{$t('crossChain.toBytom')}}</div></label>
133
134           </div>
135         </section>
136
137         <section class="form-container">
138               <div class="form-item">
139                 <label class="form-item-label">{{ $t('crossChain.asset') }}</label>
140                 <div class="form-item-content" >
141                   <v-select :options="assets" v-bind:colorBlack="true" :clearable="false" :value="selectAsset" :onChange="assetChange" label="asset">
142                     <template slot="selected-option" slot-scope="asset">
143                       <div class="asset-option">
144                         <div>{{asset.asset.symbol || 'Asset'}}</div>
145                         <div  class="color-grey asset-id">{{shortAddress(asset.asset.assetId)}}</div>
146                       </div>
147                     </template>
148                     <template slot="option" slot-scope="asset">
149                       <div class="asset-option">
150                         <div>{{asset.asset.symbol || 'Asset'}}</div>
151                         <div class="color-grey  asset-id">{{shortAddress(asset.asset.assetId)}}</div>
152                       </div>
153                     </template>
154                   </v-select>
155                 </div>
156               </div>
157         </section>
158
159         <div class="separator bg-gray"></div>
160         <section class="form-container">
161           <div class="">
162               <div class="form-item">
163                   <label class="form-item-label">
164                     {{ $t('transfer.quantity') }}
165
166                     <small class="float-right" style="margin-right: 8px;">{{formatCurrency(transaction.cost||0) }}</small>
167                   </label>
168                   <div class="form-item-content" style=" display: flex;">
169                       <input type="number" v-model="transaction.amount" :placeholder="bytomBalance">
170                       <span class="color-grey" style="width: 40px; font-size: 15px;position: absolute;right: 0;">{{unit}}</span>
171                   </div>
172                   <p class="small color-grey">{{$t('crossChain.amountHint')}}</p>
173               </div>
174           </div>
175           <a class="btn btn-primary" @click="send">{{ $t('transfer.send') }}</a>
176         </section>
177     </div>
178 </template>
179
180 <script>
181   import address from "@/utils/address";
182   import account from "@/models/account";
183 import transaction from "@/models/transaction";
184 import getLang from "@/assets/language/sdk";
185 import Confirm from "./transferConfirm";
186 import { BTM } from "@/utils/constants";
187 import { mapActions, mapGetters, mapState } from 'vuex'
188 import { Number as Num } from "@/utils/Number"
189   import _ from 'lodash';
190
191   const currencyInPrice = {
192     in_cny: 'cnyPrice',
193     in_usd: 'usdPrice',
194     in_btc:'btcPrice',
195     inCny: 'cnyPrice',
196     inUsd: 'usdPrice',
197     inBtc:'btcPrice'
198 }
199
200 export default {
201     components: {
202         Confirm
203     },
204     data() {
205         return {
206           selectAsset: {
207             asset:{
208               assetId: BTM,
209               symbol: "BTM",
210               decimals:8
211             }
212           },
213             show: false,
214             guid: null,
215             account: {},
216             accountBalance: 0.00,
217             fee: this.$t("transfer.feeType"),
218             feeTypeOptions: [this.$t("transfer.feeType")],
219             transaction: {
220                 type:'toVapor',
221                 asset: BTM,
222                 fee: 0,
223                 amount: "",
224                 to:'',
225                 confirmations: 1
226             }
227         };
228     },
229     computed: {
230       assets(){
231         if(this.transaction.type === 'toVapor'){
232           return this.currentAccount.balances
233         }else{
234           return this.currentAccount.vpBalances
235         }
236       },
237       address(){
238         if(this.transaction.type === 'toVapor'){
239           return this.currentAccount.address
240         }else{
241           return this.currentAccount.vpAddress
242         }
243       },
244       unit() {
245         return this.selectAsset.asset.symbol;
246       },
247       bytomBalance: function () {
248         let balance, balances
249         if(this.transaction.type === 'toVapor'){
250           balances = this.currentAccount.balances
251         }else if(this.transaction.type === 'toBytom') {
252           balances = this.currentAccount.vpBalances
253         }
254
255         if(balances && balances.length >0 ){
256             const balanceObject = balances.filter(b => b.asset.assetId === this.selectAsset.asset.assetId)[0]
257             balance = Num.formatNue(balanceObject.availableBalance, balanceObject.decimals)
258         }
259
260         if(this.transaction.type === 'toVapor'){
261           return `Bytom${this.$t("crossChain.amountPlaceHolder")}${(balance != null && balance != 0) ? balance : '0.00'}`
262         }else{
263           return `Vapor${this.$t("crossChain.amountPlaceHolder")}${(balance != null && balance != 0) ? balance : '0.00'}`
264         }
265       },
266       ...mapState([
267         'bytom'
268       ]),
269       ...mapGetters([
270         'currentAccount',
271         'accountList',
272         'net',
273         'netType',
274         'currency'
275       ])
276     },
277     watch: {
278         "transaction.amount": function (newAmount) {
279           this.transaction.cost = Number(this.selectAsset[currencyInPrice[this.currency]] * newAmount).toFixed(2);
280         },
281         account: function (newAccount) {
282             this.guid = newAccount.guid;
283         },
284         guid: function (newGuid) {
285             this.accountList.forEach(account => {
286                 if (account.guid == newGuid.guid) {
287                     this.account = account;
288                     return;
289                 }
290             });
291
292             account.balance(this.address).then(balances => {
293               let balance = 0.00
294               if(balances.length >0 ) {
295                 const balanceObject = balances.filter(b => b.asset === BTM)[0]
296                 balance = balanceObject.balance
297               }
298                 this.accountBalance = balance;
299             }).catch(error => {
300                 console.log(error);
301             });
302         }
303     },
304     methods: {
305         shortAddress: function (add) {
306           return address.short(add)
307         },
308         close: function () {
309             this.$router.go(-1)
310             this.transaction.to = "";
311             this.transaction.amount = "";
312             account.setupNet(`${this.net}${this.netType}`);
313             if(this.$route.query.type == 'popup'){
314                window.close();
315             }
316         },
317         formatCurrency: function (num) {
318           return Num.formatCurrency(num, this.currency)
319         },
320         assetChange: function (val) {
321           if(val.asset.assetId !== this.selectAsset.asset.assetId){
322             this.transaction.asset = val.asset.assetId;
323             const balances = this.assets
324             let balance = 0.00
325             if(balances.length >0 ) {
326               const balanceObject = balances.filter(b => b.asset.assetId === val.asset.assetId)[0]
327               balance = Num.formatNue(balanceObject.availableBalance, 0)
328             }
329             this.accountBalance = balance;
330             transaction.asset(val.asset.assetId).then(ret => {
331               this.selectAsset = Object.assign(ret,val)
332               this.transaction.cost = Number(ret[currencyInPrice[this.currency]] * this.transaction.amount).toFixed(2);
333             });
334           }
335         },
336         send: function () {
337           if (this.transaction.amount <= 0) {
338             this.$dialog.show({
339               body: this.$t("transfer.noneBTM")
340             });
341             return;
342           }
343
344           let loader = this.$loading.show({
345             // Optional parameters
346             container: null,
347             canCancel: true,
348             onCancel: this.onCancel
349           });
350
351           // Bytom => Vapor
352           if (this.transaction.type === 'toVapor') {
353             transaction.chainStatus().then((resp) => {
354               const address = resp.federationAddress
355               account.setupNet(`${this.net}`)
356               this.transaction.to = address
357               transaction.build(this.address, address, this.transaction.asset, this.transaction.amount, this.transaction.confirmations).then(result => {
358                 loader.hide();
359                 if (!this.transaction.fee) {
360                   this.transaction.fee = Number( _.sumBy(result, 'tx.fee'));
361                 }
362                 this.$router.push({name: 'transfer-confirm',
363                   params: {
364                     account: this.account,
365                     transaction: this.transaction,
366                     rawData: result,
367                     assetAlias: this.selectAsset.asset.symbol,
368                     type: this.$route.query.type
369                   }
370                 })
371               }).catch(error => {
372                 loader.hide();
373                 this.$dialog.show({
374                   body: getLang(error.message)
375                 });
376               });
377             })
378           }
379
380           // Vapor => Bytom
381           else {
382             const toAddress = this.account.address
383             account.setupNet(`${this.net}vapor`)
384             this.transaction.to = toAddress
385             transaction.buildCrossChain(this.address, toAddress, this.transaction.asset, this.transaction.amount, this.transaction.confirmations).then(result => {
386               loader.hide();
387               if (!this.transaction.fee) {
388                 this.transaction.fee = Number( _.sumBy(result, 'tx.fee'));
389               }
390               this.$router.push({name: 'transfer-confirm',
391                 params: {
392                   account: this.account,
393                   transaction: this.transaction,
394                   rawData: result,
395                   assetAlias: this.selectAsset.asset.symbol,
396                   type: this.$route.query.type
397                 }
398               })
399             }).catch(error => {
400               loader.hide();
401               this.$dialog.show({
402                 body: getLang(error.message)
403               });
404             });
405           }
406         }
407
408     }, mounted() {
409         //detect injection
410         if(this.$route.query.type === 'popup'){
411           if (this.$route.query.from != undefined) {
412               this.guid = this.$route.query.from
413               this.account = this.accountList.filter(e => e.guid === this.guid)[0]
414           }
415
416           if (this.$route.query.asset != undefined) {
417               this.transaction.asset= this.$route.query.asset
418           }
419           if (this.$route.query.to != undefined) {
420               this.transaction.to = this.$route.query.to
421           }
422           if (this.$route.query.amount != undefined) {
423               this.transaction.amount = this.$route.query.amount
424           }
425           if (this.$route.query.gas != undefined) {
426               this.transaction.fee = this.$route.query.gas
427           }
428           if(this.$route.query.confirmations != undefined) {
429               this.transaction.confirmations = this.$route.query.confirmations
430           }
431         }else{
432           this.account = this.currentAccount
433         }
434
435         const currentAsset = this.currentAccount.balances[0]
436
437         if(currentAsset){
438           transaction.asset(currentAsset.asset.assetId).then(ret => {
439             this.selectAsset = Object.assign(ret,currentAsset)
440           });
441         }
442     }
443 };
444 </script>