OSDN Git Service

add the sign transaction pop up and function.
authorZhiting Lin <zlin035@uottawa.ca>
Wed, 26 Feb 2020 02:18:57 +0000 (10:18 +0800)
committerZhiting Lin <zlin035@uottawa.ca>
Wed, 26 Feb 2020 02:18:57 +0000 (10:18 +0800)
src/background.js
src/content.js
src/dapp.js
src/messages/types.js
src/models/transaction.js
src/prompts/PromptTypes.js
src/router.js
src/utils/Number.js
src/views/sendTransaction/signTransaction.vue [new file with mode: 0644]

index 00a71af..6461fbb 100644 (file)
@@ -36,6 +36,9 @@ export default class Background {
       case MsgTypes.SEND:
         this.send(sendResponse, message.payload)
         break
+      case MsgTypes.SIGNTRANSACTION:
+        this.signTransaction(sendResponse, message.payload)
+        break
       case MsgTypes.SIGNMESSAGE:
         this.signMessage(sendResponse, message.payload)
         break
@@ -174,6 +177,13 @@ export default class Background {
 
   }
 
+  signTransaction(sendResponse, payload) {
+    NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN_TRANSACTION, '', payload ,approved => {
+      sendResponse(approved);
+    }));
+
+  }
+
   requestCurrentAccount(sendResponse, payload){
     Background.load(bytom => {
       const domain = payload.domain;
index 888c3c4..e70a4f3 100644 (file)
@@ -100,6 +100,7 @@ class Content {
         this.sync(msg)
         break
       case MsgTypes.TRANSFER:
+      case MsgTypes.SIGNTRANSACTION:
       case MsgTypes.ADVTRANSFER:
       case MsgTypes.SIGNMESSAGE:
       case MsgTypes.SEND:
index dcc13d1..f99d089 100644 (file)
@@ -79,6 +79,10 @@ export default class Bytomdapp {
     return _send(MsgTypes.TRANSFER, params)
   }
 
+  sign_transaction(params) {
+    return _send(MsgTypes.SIGNTRANSACTION, params)
+  }
+
   send_advanced_transaction(params) {
     return _send(MsgTypes.ADVTRANSFER, params)
   }
index d2825c2..6523048 100644 (file)
@@ -6,6 +6,7 @@ export const AUTHENTICATE = 'authenticate'
 export const TRANSFER = 'transfer'
 export const ENABLE = 'enable'
 export const ADVTRANSFER = 'advTransfer'
+export const SIGNTRANSACTION = 'signTransaction'
 export const SIGNMESSAGE = 'signMessage'
 export const SEND = 'send'
 export const LOAD = 'load';
index 35bc544..7eef434 100644 (file)
@@ -100,6 +100,20 @@ transaction.buildTransaction = function(guid, inputs, outputs, gas, confirmation
   return retPromise;
 };
 
+transaction.signTransaction = function(guid, transaction, password) {
+  let retPromise = new Promise((resolve, reject) => {
+    bytom.transaction
+      .signTransaction(guid, JSON.stringify(transaction), password)
+      .then(res => {
+        resolve(res);
+      })
+      .catch(error => {
+        reject(error);
+      });
+  });
+  return retPromise;
+};
+
 transaction.transfer = function(guid, transaction, password) {
   let retPromise = new Promise((resolve, reject) => {
     bytom.transaction
index b865426..d55de7f 100644 (file)
@@ -1,5 +1,6 @@
 export const REQUEST_AUTH = 'enable';
 export const REQUEST_SIGN = 'signMessage';
+export const REQUEST_SIGN_TRANSACTION = 'signTransaction';
 export const REQUEST_ADVANCED_TRANSFER = 'advancedTransfer';
 export const REQUEST_TRANSFER = 'transfer';
 export const REQUEST_ADD_NETWORK = 'requestAddNetwork';
index 51506bd..4339f6c 100644 (file)
@@ -114,6 +114,14 @@ const routers = [
         }
       },
       {
+        path: '/signTransaction',
+        name: 'sign-transaction',
+        meta: { title: '签名交易' },
+        component: resolve => {
+          require(['@/views/sendTransaction/signTransaction.vue'], resolve)
+        }
+      },
+      {
         path: '/enable',
         name: 'enable',
         meta: { title: '授权' },
index 7c5fa5e..301e60f 100644 (file)
@@ -49,13 +49,13 @@ export class Number {
     let n = new BigNumber(num);
     switch(type){
       case "in_cny":
-        return `¥ ${n.toFormat()}`
+        return `¥ ${n.toFormat(2)}`
       case "in_usd":
         return `$ ${n.toFormat()}`
       case "in_btc":
         return `₿ ${n.toFormat()}`
       default:
-        return `¥ ${n.toFormat()}`
+        return `¥ ${n.toFormat(2)}`
     }
   }
 
diff --git a/src/views/sendTransaction/signTransaction.vue b/src/views/sendTransaction/signTransaction.vue
new file mode 100644 (file)
index 0000000..b11639f
--- /dev/null
@@ -0,0 +1,274 @@
+<style lang="" scoped>
+  .warp {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 600px;
+    z-index: 2;
+    overflow: scroll;
+  }
+  .header {
+    display: flex;
+  }
+  .header p{
+    text-align: center;
+    width: 280px;
+    padding-top: 17px;
+  }
+
+  .content {
+    margin: 20px;
+    padding: 20px;
+    overflow: hidden;
+    border-radius:4px;
+    width: 280px;
+  }
+  .divider {
+    margin: 12px 0;
+  }
+
+  .value .uint {
+    font-size: 12px;
+    margin-left: 3px;
+  }
+  .btn-inline .btn {
+    margin: 10px 15px;
+  }
+  .row{
+    word-break: break-all;
+  }
+  .col{
+    font-size: 14px;
+    width: 35%;
+  }
+  .label{
+    color: #7B7B7B;
+  }
+  .value{
+    color: #282828;
+    width: 60%;
+  }
+  table{
+    width: 100%;
+  }
+  .form-item{
+    padding:0;
+    margin:0;
+    margin-bottom: 10px;
+  }
+  .hide{
+    width: 175px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .view-link{
+    font-size: 14px;
+    color: #035BD4;
+    width: 275px;
+    display: block;
+  }
+</style>
+
+<template>
+  <div class="warp bg-gray">
+    <section class="header bg-header">
+      <i class="iconfont icon-back" @click="close"></i>
+      <p>{{ $t('transfer.confirmTransaction') }}</p>
+    </section>
+
+    <section class="content bg-white">
+      <table>
+        <tbody>
+          <tr class="row">
+            <td class="col label">{{ $t('transfer.from') }}</td>
+            <td class="col value">{{currentAccount.alias}}</td>
+          </tr>
+          <div class="divider"></div>
+          <tr class="row">
+            <td class="col label">Input</td>
+            <td class="col value" v-bind:class="{ hide: !full }" >{{transaction.input}}</td>
+          </tr>
+          <tr class="row">
+            <td class="col label">Output</td>
+            <td class="col value" v-bind:class="{ hide: !full }" >{{transaction.output}}</td>
+          </tr>
+          <tr v-if="transaction.args" class="row">
+            <td class="col label">Args</td>
+            <td class="col value" v-bind:class="{ hide: !full }" >{{transaction.args}}</td>
+          </tr>
+          <tr class="row">
+            <td colspan="2" class="center-text">
+              <a v-on:click="full = !full"  class="view-link">
+                {{ full? $t('transfer.hideAll'): $t('transfer.viewAll') }} >>
+              </a>
+            </td>
+          </tr>
+
+          <div class="divider"></div>
+
+          <tr v-for="(amountInput, index) in transaction.amounts" :key="index" class="row">
+            <td class="col label">{{index ==0 && $t('transfer.transferAmount') }}</td>
+            <td class="col value">{{amountInput.amount}}<span class="uint uppercase">{{amountInput.alias || amountInput.asset}}</span></td>
+          </tr>
+
+          <tr class="row">
+            <td class="col label">{{ $t('transfer.fee') }}</td>
+            <td class="col value">{{transaction.fee}}<span class="uint">BTM</span></td>
+          </tr>
+
+        </tbody>
+      </table>
+    </section>
+    <section class="content bg-white">
+      <div class="form">
+        <div class="form-item">
+          <label class="form-item-label">{{ $t('transfer.confirmPassword') }}</label>
+          <div class="form-item-content">
+            <input type="password"  v-model="password" autofocus>
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <div class="row" style="margin: 20px;">
+      <div class="btn bg-green" @click="transfer">{{ $t('transfer.confirm') }}</div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import transaction from "@/models/transaction";
+import getLang from "@/assets/language/sdk";
+import { LocalStream } from 'extension-streams';
+import {apis} from '@/utils/BrowserApis';
+import NotificationService from '../../services/NotificationService'
+import { mapActions, mapGetters, mapState } from 'vuex'
+import _ from 'lodash';
+import account from "@/models/account";
+import { Number as Num } from "@/utils/Number"
+
+
+
+export default {
+    data() {
+        return {
+            full: false,
+            transaction: {
+                input: "",
+                output: "",
+                args: "",
+                fee: "",
+                confirmations:1,
+                amounts: []
+            },
+            password:'',
+            prompt:''
+        };
+    },
+    computed: {
+      ...mapGetters([
+        'currentAccount',
+        'net',
+        'netType',
+      ])
+    },
+    watch: {
+    },
+    methods: {
+        close: function () {
+            NotificationService.close();
+        },
+        transfer: function () {
+            let loader = this.$loading.show({
+                // Optional parameters
+                container: null,
+                canCancel: true,
+                onCancel: this.onCancel
+            });
+
+            if(Array.isArray(this.prompt.data)){
+                Promise.all(this.prompt.data.map( (rawdata) => transaction.signTransaction(this.currentAccount.guid, rawdata, this.password)))
+                    .then( (result) => {
+                        loader.hide();
+                        this.prompt.responder(result);
+                        this.$dialog.show({
+                            type: 'success',
+                            body: this.$t("transfer.success")
+                        });
+                      NotificationService.close();
+                    }).catch(error => {
+                        loader.hide();
+
+                        this.$dialog.show({
+                            body: getLang(error.message)
+                        });
+                    });
+            }else{
+                transaction.signTransaction(this.currentAccount.guid,  this.prompt.data,  this.password).then( (result) => {
+                    loader.hide();
+                    this.prompt.responder(result);
+                    this.$dialog.show({
+                        type: 'success',
+                        body: this.$t("transfer.success")
+                    });
+                    NotificationService.close();
+                }).catch(error => {
+                    loader.hide();
+
+                    this.$dialog.show({
+                        body: getLang(error.message)
+                    });
+                });
+            }
+
+        },
+      queryAsset: function(assetID){
+        return transaction.asset(assetID)
+      }
+    }, mounted() {
+          this.prompt = window.data || apis.extension.getBackgroundPage().notification || null;
+
+          if(this.prompt.data !== undefined){
+              const param = Array.isArray(this.prompt.data)? this.prompt.data[0].tx : this.prompt.data.tx
+              if(param.inputs !== undefined){
+                 this.transaction.input = param.inputs
+              }
+              if(param.outputs !== undefined){
+                  this.transaction.output = param.outputs
+              }
+              if(param.fee !== undefined){
+                 this.transaction.fee = param.fee/100000000
+              }
+
+              const array = param.inputs.filter(action => action.type ==='spend')
+
+              if(array.length>0){
+                account.setupNet(`${this.net}${this.netType}`)
+              const promise =
+                _(array)
+                  .groupBy('asset')
+                  .map((objs, key) => {
+                    return this.queryAsset(key).then(resp =>{
+                      return {
+                        'asset': key,
+                        'alias':resp.alias,
+                        'amount':Num.formatNue( _.sumBy(objs, 'amount'), resp.decimals)
+                      }
+                    })
+                  })
+
+                let that = this;
+                Promise.all(promise).then(function(output) {
+                  that.transaction.amounts = output
+                })
+
+              }
+
+
+          }
+      }
+};
+</script>