修改转账流程

This commit is contained in:
cebgcontract 2022-03-18 15:23:08 +08:00
parent 232c0f0f93
commit acf9a2cf97
5 changed files with 114 additions and 28 deletions

View File

@ -7,6 +7,7 @@ import { Message } from 'element-ui'
import { Chain } from '@/chain/Chain' import { Chain } from '@/chain/Chain'
import { AVAILABLE_CHAINS, IChainData } from '@/configs/config_chain' import { AVAILABLE_CHAINS, IChainData } from '@/configs/config_chain'
import { AllChains } from '@/configs/allchain' import { AllChains } from '@/configs/allchain'
import { parsePrice } from '@/utils/chain.util'
@singleton @singleton
export default class ChainManager { export default class ChainManager {
@ -136,4 +137,28 @@ export default class ChainManager {
console.log('balance: ', balance) console.log('balance: ', balance)
return balance return balance
} }
// 转账
public async transferToAccount({ to, amount, chainId, address } : {
to: string
amount: number
chainId: number
address: string}) {
const self = this
if (chainId !== this.bc.currentChain) {
return new Promise((resolve, reject) => {
this.bc.switchEthereumChain(chainId, function() {
self.bc.transferToAccount(to, amount, address)
.then(res => {
resolve && resolve(res)
})
.catch(err => {
reject && reject(err)
})
})
})
} else {
return this.bc.transferToAccount(to, amount, address)
}
}
} }

View File

@ -58,7 +58,11 @@ export class Blockchain {
} }
public get hexChainId() { public get hexChainId() {
return '0x' + this.currentChain.toString(16) return this.toHexChainId(this.currentChain)
}
public toHexChainId(chainId: number) {
return '0x' + chainId.toString(16)
} }
public async chainSelected(id: number) { public async chainSelected(id: number) {
@ -213,13 +217,11 @@ export class Blockchain {
} }
public async getCoinInstance(address: string) { public async getCoinInstance(address: string) {
if (this.coinInstanceMap.has(address)) { if (!this.coinInstanceMap.has(address)) {
return this.coinInstanceMap.get(address)
} else {
const coinInstance = await this.initInstance({ abi: ERC20ABI, address, account: AppModule.accountId }) const coinInstance = await this.initInstance({ abi: ERC20ABI, address, account: AppModule.accountId })
this.coinInstanceMap.set(address, coinInstance) this.coinInstanceMap.set(address, coinInstance)
return coinInstance
} }
return this.coinInstanceMap.get(address)
} }
public clearCachedProvider() { public clearCachedProvider() {
@ -285,6 +287,8 @@ export class Blockchain {
console.log('chainChanged', chainId) console.log('chainChanged', chainId)
const chainIdNum = parseInt(chainId) const chainIdNum = parseInt(chainId)
await this.checkChain(chainIdNum) await this.checkChain(chainIdNum)
this.currentChain = chainIdNum
this.saveProvider()
}) })
// Subscribe to session disconnection // Subscribe to session disconnection
@ -293,26 +297,35 @@ export class Blockchain {
}) })
} }
async switchEthereumChain() { async switchEthereumChain(chainId?: number, cb?: () => void) {
chainId = chainId || this.currentChain
const hexChainId = this.toHexChainId(chainId)
const onChainChange = (chainId: string) => {
console.log('switchEthereumChain: ', chainId)
this.provider.removeListener('chainChanged', onChainChange)
cb && cb()
}
this.provider.on('chainChanged', onChainChange)
try { try {
await this.provider.request({ await this.provider.request({
method: 'wallet_switchEthereumChain', method: 'wallet_switchEthereumChain',
params: [{ chainId: this.hexChainId }] params: [{ chainId: hexChainId }]
}) })
console.log('switch chain success')
} catch (e: any) { } catch (e: any) {
console.log('switch chain error: ', e) console.log('switch chain error: ', e)
if (e.code === 4902) { if (e.code === 4902) {
try { try {
const data = this.chainMap.get(this.currentChain)! const data = this.chainMap.get(chainId)!
await this.provider.request({ await this.provider.request({
method: 'wallet_addEthereumChain', method: 'wallet_addEthereumChain',
params: [ params: [
{ {
chainId: this.hexChainId, chainId: hexChainId,
chainName: data.name, chainName: data.name,
nativeCurrency: { nativeCurrency: {
name: data.symbol, name: data.symbol,
symbol: data.symbol, symbol: data.symbol || 18,
decimals: data.decimals decimals: data.decimals
}, },
blockExplorerUrls: [data.explorerurl], blockExplorerUrls: [data.explorerurl],
@ -320,8 +333,10 @@ export class Blockchain {
} }
] ]
}) })
console.log('add chain success')
} catch (addError) { } catch (addError) {
console.error('add chain error: ', addError) console.error('add chain error: ', addError)
this.provider.removeListener('chainChanged', onChainChange)
} }
} }
// console.error(e) // console.error(e)
@ -382,10 +397,19 @@ export class Blockchain {
*/ */
public async getBalance(address: string, account: string | null) { public async getBalance(address: string, account: string | null) {
account = account || AppModule.accountId account = account || AppModule.accountId
const coinInstance: any = this.getCoinInstance(address) const coinInstance: any = await this.getCoinInstance(address)
return await coinInstance.methods.balanceOf(account).call() return await coinInstance.methods.balanceOf(account).call()
} }
// 转账
public async transferToAccount(account: string, amount: number, address: string) {
const amountBN = this.web3.utils.toBN(this.web3.utils.toWei(amount + ''))
const coinInstance: any = await this.getCoinInstance(address)
return coinInstance.methods
.transfer(account, amountBN)
.send({ gas: 1000000 })
}
public async signData(signObj: any, signer: string) { public async signData(signObj: any, signer: string) {
const msgParams = JSON.stringify(signObj) const msgParams = JSON.stringify(signObj)
const from = signer const from = signer

View File

@ -12,7 +12,7 @@
alt="coin" alt="coin"
class="topRight"></div> class="topRight"></div>
<div class="wrongNetwork hide"><span>Wrong network</span></div> <div class="wrongNetwork hide"><span>Wrong network</span></div>
<button :disabled="coinData.btnDisable" class="general-btn btn"> <button :disabled="coinData.btnDisable" class="general-btn btn" @click="onClick">
<span class="title">{{coinData.btnName}}</span> <span class="title">{{coinData.btnName}}</span>
</button> </button>
</div> </div>
@ -23,6 +23,7 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
import { AppModule, DeviceType } from '@/store/modules/app' import { AppModule, DeviceType } from '@/store/modules/app'
export interface ICoinData{ export interface ICoinData{
type: number
name: string name: string
symbol: string symbol: string
amount: number | string amount: number | string
@ -30,6 +31,8 @@ export interface ICoinData{
price: string|number price: string|number
btnName: string btnName: string
btnDisable: boolean btnDisable: boolean
chain?: number
address?: string
} }
@Component({ @Component({
@ -43,6 +46,10 @@ export default class CoinCard extends Vue {
get mobile() { get mobile() {
return AppModule.device === DeviceType.Mobile return AppModule.device === DeviceType.Mobile
} }
onClick() {
this.$emit('coin-card-clicked', this.coinData)
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -25,14 +25,22 @@
</div> </div>
<div class="wallet"> <div class="wallet">
<total-balance :currencies="currencies"></total-balance> <total-balance :currencies="currencies"></total-balance>
<coin-card v-for="d in coinList" :coin-data="d" :key="d.symbol"></coin-card> <coin-card
v-for="d in coinList"
:coin-data="d"
@coin-card-clicked = "onCardClicked"
:key="d.symbol"></coin-card>
</div> </div>
<div class="header ingame"><span class="label">Ingame Currency</span> <div class="header ingame"><span class="label">Ingame Currency</span>
</div> </div>
<div class="horizontal-bar"></div> <div class="horizontal-bar"></div>
<div class="wallet"> <div class="wallet">
<placeholder-panel></placeholder-panel> <placeholder-panel></placeholder-panel>
<coin-card v-for="d in gameCoinList" :coin-data="d" :key="d.symbol"></coin-card> <coin-card
v-for="d in gameCoinList"
:coin-data="d"
@coin-card-clicked = "onGameCardClicked"
:key="d.symbol"></coin-card>
</div> </div>
</div> </div>
</template> </template>
@ -70,7 +78,7 @@ export default class WalletPanel extends Vue {
@Watch('logined') @Watch('logined')
private accountChange() { private accountChange() {
this.updateBalanceSet() this.changeNet(this.nets[0].id)
this.updateCurrencies() this.updateCurrencies()
} }
@ -79,6 +87,7 @@ export default class WalletPanel extends Vue {
private coinList: ICoinData[] = [ private coinList: ICoinData[] = [
{ {
name: 'CEBG Coin', name: 'CEBG Coin',
type: 0,
symbol: 'cec', symbol: 'cec',
amount: '-', amount: '-',
icon: require('@/assets/market/cec.png'), icon: require('@/assets/market/cec.png'),
@ -88,6 +97,7 @@ export default class WalletPanel extends Vue {
}, },
{ {
name: 'CEBG Gem', name: 'CEBG Gem',
type: 0,
symbol: 'ceg', symbol: 'ceg',
amount: '-', amount: '-',
icon: require('@/assets/market/ceg.png'), icon: require('@/assets/market/ceg.png'),
@ -100,6 +110,7 @@ export default class WalletPanel extends Vue {
private gameCoinList: ICoinData[] = [ private gameCoinList: ICoinData[] = [
{ {
name: 'CEBG Coin', name: 'CEBG Coin',
type: 1,
symbol: 'gCEC', symbol: 'gCEC',
amount: '-', amount: '-',
icon: require('@/assets/market/cec.png'), icon: require('@/assets/market/cec.png'),
@ -109,6 +120,7 @@ export default class WalletPanel extends Vue {
}, },
{ {
name: 'CEBG Gem', name: 'CEBG Gem',
type: 1,
symbol: 'gCEG', symbol: 'gCEG',
amount: '-', amount: '-',
icon: require('@/assets/market/ceg.png'), icon: require('@/assets/market/ceg.png'),
@ -133,6 +145,7 @@ export default class WalletPanel extends Vue {
data.amount = '-' data.amount = '-'
data.price = '-' data.price = '-'
data.btnDisable = true data.btnDisable = true
return data
} }
get showAccount() { get showAccount() {
@ -161,9 +174,12 @@ export default class WalletPanel extends Vue {
changeNet(net: number) { changeNet(net: number) {
this.currentNet = net this.currentNet = net
const chainData = CONTRACT_ADDRESS[net]
for (let i = 0, l = this.coinList.length; i < l; i++) { for (let i = 0, l = this.coinList.length; i < l; i++) {
this.updateDefaultData(this.coinList[i]) const data = this.updateDefaultData(this.coinList[i])
this.$set(this.coinList, i, this.coinList[i]) data.chain = net
data.address = chainData[data.symbol]
this.$set(this.coinList, i, data)
} }
this.updateBalanceSet() this.updateBalanceSet()
} }
@ -184,16 +200,30 @@ export default class WalletPanel extends Vue {
const cec = await this.chainManager.getBalance(currentData.cec, this.currentNet) const cec = await this.chainManager.getBalance(currentData.cec, this.currentNet)
const ceg = await this.chainManager.getBalance(currentData.ceg, this.currentNet) const ceg = await this.chainManager.getBalance(currentData.ceg, this.currentNet)
console.log(formatPrice(cec, 18), formatPrice(ceg, 18)) console.log(formatPrice(cec, 18), formatPrice(ceg, 18))
const cecData = this.coinList[0] const updateCoinData = (i: number, amount: number) => {
cecData.amount = formatPrice(cec, 18) const cecData = this.coinList[i]
cecData.btnDisable = cec === 0 cecData.amount = formatPrice(amount, 18)
this.$set(this.coinList, 0, cecData) cecData.btnDisable = amount === 0
this.$set(this.coinList, i, cecData)
const cegData = this.coinList[1]
cegData.amount = formatPrice(ceg, 18)
cegData.btnDisable = ceg === 0
this.$set(this.coinList, 1, cegData)
} }
updateCoinData(0, cec)
updateCoinData(1, ceg)
}
}
async onCardClicked(data: ICoinData) {
console.log('on coin card clicked: ', data)
const res = await this.chainManager.transferToAccount({
to: '0x42448C6a38c08637218D8327b748F213fC2c0231',
amount: 1,
chainId: data.chain!,
address: data.address!
})
console.log(res)
}
async onGameCardClicked(data: ICoinData) {
console.log('on game card clicked: ', data)
} }
} }
</script> </script>

View File

@ -75,7 +75,7 @@ export const AllChains = [
name: 'Binance Smart Chain', name: 'Binance Smart Chain',
type: 'Mainnet', type: 'Mainnet',
rpc: 'https://rpc.ankr.com/bsc', rpc: 'https://rpc.ankr.com/bsc',
logo: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzMiAzMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzIgMzI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMDA5M0REO30KCS5zdDF7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkZGRkZGO30KPC9zdHlsZT4KPGc+Cgk8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTEzLjUsMTZsNS4yLDUuM0wyMiwxOGMwLjYtMC42LDEuNS0wLjYsMiwwYzAsMCwwLDAsMCwwYzAuNiwwLjYsMC42LDEuNiwwLDIuMmwtNC4zLDQuNAoJCWMtMC42LDAuNi0xLjUsMC42LTIuMSwwYzAsMCwwLDAsMCwwbC02LjItNi40VjIyYzAsMC44LTAuNywxLjUtMS41LDEuNWMtMC44LDAtMS41LTAuNy0xLjUtMS41VjEwYzAtMC44LDAuNy0xLjUsMS41LTEuNQoJCWMwLjgsMCwxLjUsMC43LDEuNSwxLjV2My44bDYuMi02LjRjMC42LTAuNiwxLjUtMC42LDIuMSwwYzAsMCwwLDAsMCwwbDQuMyw0LjRjMC42LDAuNiwwLjYsMS42LDAsMi4yYy0wLjYsMC42LTEuNSwwLjYtMiwwCgkJYzAsMCwwLDAsMCwwbC0zLjMtMy40TDEzLjUsMTZ6IE0xOC43LDE0LjVjMC44LDAsMS41LDAuNywxLjUsMS41cy0wLjcsMS41LTEuNSwxLjVzLTEuNS0wLjctMS41LTEuNQoJCUMxNy4yLDE1LjIsMTcuOSwxNC41LDE4LjcsMTQuNXoiLz4KPC9nPgo8L3N2Zz4K', logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCAyMDAwIDIwMDAiPjxnIGZpbGw9IiNmM2JhMmYiPjxwYXRoIGQ9Ik02MTEuNTkgODQwLjQybDM4OC40LTM4OC4zOSAzODguNiAzODguNTkgMjI2LTIyNkw5OTkuOTkgMCAzODUuNiA2MTQuNDJsMjI1Ljk5IDIyNk0uMDA2IDk5OS45NjlsMjI2LjAwNy0yMjYuMDA3IDIyNS45OTIgMjI1Ljk5M0wyMjYgMTIyNS45NnpNNjExLjU5IDExNTkuNThsMzg4LjQgMzg4LjM5IDM4OC41OS0zODguNTggMjI2LjEyIDIyNS44OC0uMTEuMTJMOTk5Ljk5IDIwMDBsLTYxNC40MS02MTQuNC0uMzItLjMyIDIyNi4zMy0yMjUuN00xNTQ4LjAxMyAxMDAwLjA5M2wyMjYuMDA3LTIyNi4wMDYgMjI1Ljk5MiAyMjUuOTkyLTIyNi4wMDYgMjI2LjAwN3oiLz48cGF0aCBkPSJNMTIyOS4yMiA5OTkuODhoLjFMOTk5Ljk5IDc3MC41NSA4MzAuNTEgOTQwLjAzaC0uMDFsLTE5LjQ3IDE5LjQ4LTQwLjE2IDQwLjE3LS4zMi4zMS4zMi4zMyAyMjkuMTIgMjI5LjEzIDIyOS4zMy0yMjkuMzMuMTEtLjEzLS4yMS0uMTEiLz48L2c+PC9zdmc+',
id: 56, id: 56,
symbol: 'BNB', symbol: 'BNB',
explorerurl: 'https://bscscan.com' explorerurl: 'https://bscscan.com'
@ -101,7 +101,7 @@ export const AllChains = [
type: 'Testnet', type: 'Testnet',
rpc: 'https://data-seed-prebsc-1-s1.binance.org:8545/', rpc: 'https://data-seed-prebsc-1-s1.binance.org:8545/',
id: 97, id: 97,
logo: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzMiAzMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzIgMzI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMDA5M0REO30KCS5zdDF7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkZGRkZGO30KPC9zdHlsZT4KPGc+Cgk8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTEzLjUsMTZsNS4yLDUuM0wyMiwxOGMwLjYtMC42LDEuNS0wLjYsMiwwYzAsMCwwLDAsMCwwYzAuNiwwLjYsMC42LDEuNiwwLDIuMmwtNC4zLDQuNAoJCWMtMC42LDAuNi0xLjUsMC42LTIuMSwwYzAsMCwwLDAsMCwwbC02LjItNi40VjIyYzAsMC44LTAuNywxLjUtMS41LDEuNWMtMC44LDAtMS41LTAuNy0xLjUtMS41VjEwYzAtMC44LDAuNy0xLjUsMS41LTEuNQoJCWMwLjgsMCwxLjUsMC43LDEuNSwxLjV2My44bDYuMi02LjRjMC42LTAuNiwxLjUtMC42LDIuMSwwYzAsMCwwLDAsMCwwbDQuMyw0LjRjMC42LDAuNiwwLjYsMS42LDAsMi4yYy0wLjYsMC42LTEuNSwwLjYtMiwwCgkJYzAsMCwwLDAsMCwwbC0zLjMtMy40TDEzLjUsMTZ6IE0xOC43LDE0LjVjMC44LDAsMS41LDAuNywxLjUsMS41cy0wLjcsMS41LTEuNSwxLjVzLTEuNS0wLjctMS41LTEuNQoJCUMxNy4yLDE1LjIsMTcuOSwxNC41LDE4LjcsMTQuNXoiLz4KPC9nPgo8L3N2Zz4K', logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCAyMDAwIDIwMDAiPjxnIGZpbGw9IiNmM2JhMmYiPjxwYXRoIGQ9Ik02MTEuNTkgODQwLjQybDM4OC40LTM4OC4zOSAzODguNiAzODguNTkgMjI2LTIyNkw5OTkuOTkgMCAzODUuNiA2MTQuNDJsMjI1Ljk5IDIyNk0uMDA2IDk5OS45NjlsMjI2LjAwNy0yMjYuMDA3IDIyNS45OTIgMjI1Ljk5M0wyMjYgMTIyNS45NnpNNjExLjU5IDExNTkuNThsMzg4LjQgMzg4LjM5IDM4OC41OS0zODguNTggMjI2LjEyIDIyNS44OC0uMTEuMTJMOTk5Ljk5IDIwMDBsLTYxNC40MS02MTQuNC0uMzItLjMyIDIyNi4zMy0yMjUuN00xNTQ4LjAxMyAxMDAwLjA5M2wyMjYuMDA3LTIyNi4wMDYgMjI1Ljk5MiAyMjUuOTkyLTIyNi4wMDYgMjI2LjAwN3oiLz48cGF0aCBkPSJNMTIyOS4yMiA5OTkuODhoLjFMOTk5Ljk5IDc3MC41NSA4MzAuNTEgOTQwLjAzaC0uMDFsLTE5LjQ3IDE5LjQ4LTQwLjE2IDQwLjE3LS4zMi4zMS4zMi4zMyAyMjkuMTIgMjI5LjEzIDIyOS4zMy0yMjkuMzMuMTEtLjEzLS4yMS0uMTEiLz48L2c+PC9zdmc+',
symbol: 'BNB', symbol: 'BNB',
explorerurl: 'https://testnet.bscscan.com' explorerurl: 'https://testnet.bscscan.com'
}, },