UNPKG

vue-tronlink

Version:

Vue support for the TronLink browser extension

515 lines (440 loc) 16.7 kB
import {Address} from "./base/Address" import {TokenTrc20} from "./TokenTrc20"; import { TronLinkEventCaller, TronLinkTabReply, TronLinkToken, TronLinkTunnelMessage, TronMapContract, TronTRC20Token } from "./base/types"; import {Vue} from "vue/types/vue"; import CoinDetail from "./CoinDetail"; import {txtUnit} from "../utils/bnx" /** * TronLink extension interaction functionality */ export default class TronLink { tronWeb: any tokens: TronLinkToken contracts: TronMapContract selected_function_reply: string selected_function_human_operation: string selected_function_caller: TronLinkEventCaller debug: boolean = false /** * Initiates TronLink support object. * * @param {Object} tronWeb tronWeb entity object * (details: https://github.com/tronprotocol/tron-web) */ constructor(tronWeb) { this.tronWeb = tronWeb this.tokens = {} this.selected_function_human_operation = "" if (window && !window.hasOwnProperty("__tronlinkbase_codex")) { // @ts-ignore window.__tronlinkbase_codex = this } } public static Instance(): (TronLink | any | boolean) { if (window && window.hasOwnProperty("__tronlinkbase_codex")) { // @ts-ignore const obj = window.__tronlinkbase_codex if (obj instanceof TronLink) { return (obj) as TronLink } else { return (obj) as TronLink } } else { return false } } setDebug(x: boolean): void { this.debug = x } /** * Checks if TronLink browser extension is installed */ isInstalled(): boolean { return !!this.tronWeb } /** * Checks if user is logged in to the TronLink plugin */ isLoggedIn(): boolean { return this.tronWeb && this.tronWeb.ready } /** * Checks if user is logged in to the TronLink plugin. * Alias for isLoggedIn() method. */ isUnlocked(): boolean { return this.isLoggedIn() } /** * Returns logged in user Tron address */ getAccountAddress(): string { return this.tronWeb.defaultAddress.base58 } /** * returns the address with 41e... */ getAccountAddressHex(): string { return this.tronWeb.defaultAddress.hex } /** * returns the address with 0x... */ getAccountAddress0x(): string { return "0x" + this.getAccountAddressHex().substr(2) } NewContract(abi: any[] = [], address: boolean = false): any { return new this.tronWeb.Contract(this.tronWeb, abi, address) } removeAllFunctionCalls(): void { this.selected_function_human_operation = "" } /** * Converts Tron address from one format to another. * * @param {String, Number} address Address to convert * @param {String} fromFormat From format string * @param {String} toFormat To format string */ convertAddress(address, fromFormat: string, toFormat: string): string { if (fromFormat == toFormat) { throw "From and To address formats are equal" } switch (toFormat) { case "hex": switch (fromFormat) { case "base58": case "tron": case "trx": return "0x" + this.tronWeb.address.toHex(address) } break case "base58": case "tron": case "trx": switch (fromFormat) { case "hex": if (!Address.isHexAddress(address)) { throw "Invalid hex address" } if (address.startsWith("0x")) { address = address.substr(2) } return this.tronWeb.address.fromHex(address) } break } throw "Invalid address formats" } /** * doesnt work on the older version * @deprecated */ async coinTRX(): Promise<number> { let wallet_trx_coin = 0 wallet_trx_coin = await this.tronWeb.trx.getBalance(this.getAccountAddress()) return wallet_trx_coin } /** * the working version of get balance of coin trx the simple way * @param cb function callback * @param cberr function callback */ getCoinTRX(cb, cberr): void { this.tronWeb.trx.getBalance(this.getAccountAddress(), (err, x) => { if (err == null) { cb(x) } else { cberr(err) } }) } async getCoin(trc20_coin: string): Promise<number> { return await this.getThirdTokenBalanceSun(this.getAccountAddress(), trc20_coin) } async getCoinFlo(trc20_coin: string): Promise<number> { return await this.getThirdTokenBalanceFloat(this.getAccountAddress(), trc20_coin) } async coinDPFlo(): Promise<number> { return await this.getCoinFlo("TXHvwxYbqsDqTCQ9KxNFj4SkuXy7EF2AHR") } async coinCOLAFlo(): Promise<number> { return await this.getCoinFlo("TSNWgunSeGUQqBKK4bM31iLw3bn9SBWWTG") } async coinBTCFlo(): Promise<number> { return await this.getCoinFlo("TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9") } async coinETHFlo(): Promise<number> { return await this.getCoinFlo("THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF") } async coinSUNFlo(): Promise<number> { return await this.getCoinFlo("TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9") } async coinUSDTFlo(): Promise<number> { return await this.getCoinFlo("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t") } async coinDP(): Promise<number> { return await this.getCoin("TXHvwxYbqsDqTCQ9KxNFj4SkuXy7EF2AHR") } async coinCOLA(): Promise<number> { return await this.getCoin("TSNWgunSeGUQqBKK4bM31iLw3bn9SBWWTG") } async coinBTC(): Promise<number> { return await this.getCoin("TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9") } async coinETH(): Promise<number> { return await this.getCoin("THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF") } async coinSUN(): Promise<number> { return await this.getCoin("TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9") } async coinUSDT(): Promise<number> { return await this.getCoin("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t") } async getMyCoinDetail(trc20_coin: string): Promise<CoinDetail> { return await this.getCoinDetail(this.getAccountAddress(), trc20_coin) } async coinDPDetail(): Promise<CoinDetail> { return await this.getMyCoinDetail("TXHvwxYbqsDqTCQ9KxNFj4SkuXy7EF2AHR") } async coinCOLADetail(): Promise<CoinDetail> { return await this.getMyCoinDetail("TSNWgunSeGUQqBKK4bM31iLw3bn9SBWWTG") } async coinBTCDetail(): Promise<CoinDetail> { return await this.getMyCoinDetail("TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9") } async coinETHDetail(): Promise<CoinDetail> { return await this.getMyCoinDetail("THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF") } async coinSUNDetail(): Promise<CoinDetail> { return await this.getMyCoinDetail("TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9") } async coinUSDTDetail(): Promise<CoinDetail> { return await this.getMyCoinDetail("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t") } /** * get TRC20 token in balance * @param address * @param trc20 */ async getCoinDetail(address: string, trc20: string): Promise<CoinDetail> { if (!this.isLoggedIn()) { throw "wallet is not login" } if (!this.tokens.hasOwnProperty(trc20)) { await this.initCoinDetail(trc20, address) } else { let contract = this.contracts[trc20] if (!contract) { contract = await this.NewToken(trc20) this.contracts[trc20] = contract } const b = await contract.balanceOf(address) this.tokens[trc20].setHolder(address, txtUnit(b)) } // @ts-ignore return this.tokens[trc20]; } // @ts-ignore async initCoinDetail(trc20: string, me: string): Promise<CoinDetail> { const contract = await this.NewToken(trc20) const a = await contract.balanceOf(me) const d = await contract.decimals() const n = await contract.name() const s = await contract.symbol() const detail = new CoinDetail(trc20, d, s, n) detail.setHolder(me, txtUnit(a)) this.tokens[trc20] = detail this.contracts[trc20] = contract return detail } async getContractToken(trc20: string): Promise<TokenTrc20> { let contract = this.contracts[trc20] if (!contract) { if (this.debug) { console.log("new contract token ...") } contract = await this.NewToken(trc20) this.contracts[trc20] = contract } return contract } // @ts-ignore async sendCoin(amount: any, toaddress: string,): Promise<void> { await this.tronWeb.trx.sendTransaction(toaddress, amount, {}, (err, receipt) => { if (err === undefined) { if (this.debug) { console.log('- Output:', receipt, '\n'); } } }) } async sendTrc10Token(amount: any, tokenID: number, toaddress: string): Promise<void> { const receipt = await this.tronWeb.trx.sendToken(toaddress, amount, tokenID, {}) if (this.debug) { console.log('- Output:', receipt, '\n'); } } public async sendToken(amount: any, toaddress: string, trc20: string): Promise<void> { const contract = await this.NewToken(trc20); // @ts-ignore const send_amount = String(amount); await contract.transfer(toaddress, send_amount); } public async approveToken(trc20: string, spender_address: string, amount_sun: any): Promise<void> { const contract = await this.NewToken(trc20); const am = String(amount_sun) await contract.approve(spender_address, am) } public async getMyTokenBalance(trc20_coin: string): Promise<number> { return await this.getTokenBalanceSun(this.getAccountAddress(), trc20_coin) } async getTokenBalanceSun(address: string, trc20: string): Promise<number> { const detail = await this.getCoinDetail(address, trc20) return detail.balance(address) } async getUpdateAllowanceAmount(ins: CoinDetail, myaddress: string, spender: string): Promise<number> { if (!this.isLoggedIn()) { throw "wallet is not login" } const contract = await this.NewToken(ins.address) const allowance = await contract.allowance(myaddress, spender) const nm = txtUnit(allowance) ins.setSpender(myaddress, spender, nm) return ins.showAllowance(myaddress, spender) } async getThirdTokenBalanceSun(address: string, trc20_address: string): Promise<number> { const conver = await this.getCoinDetail(address, trc20_address) return conver.balance(address) } async getThirdTokenBalanceFloat(address: string, trc20_address: string): Promise<number> { const conver = await this.getCoinDetail(address, trc20_address) return conver.byFloat(address) } /** * to approve prespending TRC20 token on the go.. * @param trc20_address * @param spender_address * @param amount_sun * @constructor */ async ApproveSpendingToken(trc20_address: string, spender_address: string, amount_sun: number): Promise<boolean> { const token = await this.NewToken(trc20_address) return await token.approve(spender_address, String(amount_sun)) } async NewToken(trc20_address: string): Promise<TokenTrc20> { const contract = new TokenTrc20(this.tronWeb) contract.setDebug(false) await contract.init(trc20_address) return contract } getListedCoins(): TronLinkToken { return this.tokens } explainTrc20(payload: TronTRC20Token): number { const me = this.getAccountAddress() return payload.holder[me] } setCallbackFunctionCall(function_selector: string, caller: TronLinkEventCaller) { this.selected_function_human_operation = function_selector this.selected_function_caller = caller } __signOp(payload: TronLinkTunnelMessage): boolean { if (this.selected_function_human_operation == payload.data.input.function_selector) { this.selected_function_caller.signer(payload) return true } else { return false } } __signReply(payload: TronLinkTabReply): boolean { if (this.selected_function_caller != undefined && this.selected_function_human_operation != "") { this.selected_function_caller.reply(payload) this.selected_function_human_operation = "" return true } else { return false } } __debugMessage(data_message_raw: any): boolean { if (this.selected_function_caller) { this.selected_function_caller.debug(data_message_raw) return true } else { return false } } eventListener(message: any, tronLinkInitialData: boolean | any, vueInstance: Vue) { if (message.action === 'setNode') { // @ts-ignore vueInstance.announce_node_name(message.data.node.fullNode) vueInstance.$emit("notify_tron_node_change", message.data.node.fullNode) } if (message.action === 'setAccount') { if (message.hasOwnProperty("data")) { // @ts-ignore if (vueInstance.hasOwnProperty("account_name") && vueInstance.account_name !== message.data.name) { vueInstance.$emit("notify_tron_account_set", message.data.name, message.data.address) } if (message.data.name === false) { vueInstance.$emit("notify_tron_account_logout") } } } if (message.action === 'tunnel') { if (message.data.hasOwnProperty("action") && message.data.action === 'sign') { if (message.data.hasOwnProperty("input") && message.data.input.hasOwnProperty("function_selector")) { if (!this.__signOp(message.data)) { vueInstance.$emit("notify_tron_opensign", message.uuid, message.data.input.function_selector, message.data) } } else { if (!this.__signOp(message.data)) { vueInstance.$emit("notify_tron_opensign", message.uuid, message.data) } } } } if (message.action === 'tabReply') { /** * response from the wallet sign action */ if (message.data.hasOwnProperty("success")) { if (message.data.success === true) { if (!this.__signReply(message.data)) { vueInstance.$emit("notify_tron_sign_success_broadcast", message.data, message.uuid) } } else { this.removeAllFunctionCalls() } } if (!tronLinkInitialData) { if (typeof message === "object" && message.hasOwnProperty("data")) { if (message.data.hasOwnProperty("data")) { tronLinkInitialData = message.data.data; if (message.data.hasOwnProperty("node")) { // @ts-ignore vueInstance.announce_node_name(message.data.node.full_node) } vueInstance.$emit("notify_tron_initialization", tronLinkInitialData) } else { console.log(message.data) } } } } // @ts-ignore if (vueInstance.hasOwnProperty("_debug_tronlink") && vueInstance._debug_tronlink) { console.group("TronLink Message 🖼") console.log("Action:", message.action) console.log(message.data) this.__debugMessage(message) console.groupEnd() } } }