debitisimpedit
Version:
adapte eos and eth, and adapte pluin - MateMask and Scatter
414 lines (363 loc) • 11.8 kB
text/typescript
namespace eos {
export class EosApi extends base.CustomApi {
protected _scatter: Scatter | undefined
protected _eos: Eos | undefined
protected _config: EOSConfig
protected _account: IAccount | undefined
// protected miss_identity_cbk: Function | undefined
private formatEos(value: string) {
return parseFloat(value)
}
/**
*
* @param core EOS
* @param config
* @param mode
*/
public constructor(core: any, config: EosSetting, mode: string) {
super(core, mode)
this._config = new EOSConfig(config)
const win: any = window
this._scatter = win['scatter']
if (this._scatter) {
this._scatter.requireVersion(3.0)
this._eos = this._scatter.eos(this._config.eosNetwork, core, {}, this._config.protocal)
} else {
this._eos = undefined
}
}
public get eos(): Eos | undefined {
return this._eos
}
public getSymbol(): string {
return base.SymbolType.eos
} // eos或者eth
public plugin(): string {
return 'Scatter'
} // 插件名称
public usePlugin(): boolean {
return true
} // 是否使用插件
public isInitPlugin(): boolean {
return this._eos !== undefined
} // 插件是否初始化了
public hasAccount(): boolean {
return this._account !== undefined
} // 是否有账号
public defaultAccount(): string {
return this._account ? this._account.name : ''
} // 获取默认账号
public check(): boolean {
if (this.isInitPlugin()) {
// this.onError(base.ErrorCode.PluginNotInit)
this.onError(base.ErrorCode.PluginNotInit)
return false
} else if (this.hasAccount()) {
this.onError(base.ErrorCode.AccountNotFound)
return false
} else if (!this.identity) {
this.onError(base.ErrorCode.MissIdentity)
// this.miss_identity_cbk && this.miss_identity_cbk()
this.invorkEvent(EosEvent.MISS_IDENTITY, {})
return false
}
return true
}
public get identity(): Identity | undefined {
return this._scatter ? this._scatter.identity : undefined
}
public addEvent(name: string, cbk: Function): void {
// todo
}
public forgetIdentity() {
this._scatter && this._scatter.forgetIdentity()
}
protected updateStatus(): void {
super.updateStatus()
const win: any = window
if (!this._scatter) {
win['scatter'] && (this._scatter = win['scatter'])
if (this._scatter) {
this._scatter.requireVersion(3.0)
this._eos = this._scatter.eos(this._config.eosNetwork, this.core, {}, this._config.protocal)
}
}
if (this.identity) {
const name = this.defaultAccount()
this._account = this.identity.accounts.find(accound => {
return accound.blockchain === 'eos'
})
if (name !== this.defaultAccount()) {
// this.account_changed_cbk && this.account_changed_cbk(this.defaultAccount(), name)
this.invorkEvent(base.BaseEvent.ACCOUNT_CHANGED, {
account: this.defaultAccount(),
oldAccount: name
})
}
}
}
// public onMissItentity(cbk: Function): EosApi {
// this.miss_identity_cbk = cbk
// return this
// }
public encode(value: string): string {
return this.core.modules.format.encodeName(value, false)
}
public decode(value: string): string {
return this.core.modules.format.decodeName(value.toString(), false)
}
public async requireIdentity() {
if (!this._scatter) {
this.onError(base.ErrorCode.PluginNotInit)
throw { errorCode: base.ErrorCode.PluginNotInit }
}
try {
const res = await this._scatter.getIdentity({ accounts: [this._config.eosNetwork] })
if (res) {
this._account = res.accounts.find(accound => {
return accound.blockchain === 'eos'
})
return res
} else {
this.onError(base.ErrorCode.AccountNotFound)
throw { errorCode: base.ErrorCode.AccountNotFound }
}
} catch (e) {
throw e
}
}
public async getBalance() {
let eos = this.eos
if (!eos) return 0
const res = await eos.getCurrencyBalance('eosio.token', this.defaultAccount(), this.getSymbol().toUpperCase())
return res && res.length > 0 ? parseFloat(res[0]) : 0
}
public getAccountInfo() {
let eos = this.eos
if (!eos) return undefined
return eos.getAccount(this.defaultAccount())
}
public transaction(account: IAccount, to: string, currency: string, memo: string = '') {
let eos = this.eos
if (!eos) return undefined
return eos.transaction(
{
actions: [
{
account: 'eosio.token',
name: 'transfer',
authorization: [
{
actor: account.name,
permission: account.authority
}
],
data: {
from: account.name,
to: to,
quantity: currency, // 注意 要4位小数
memo: memo
}
}
]
},
{ broadcast: true, sign: true }
)
}
public getAuthorization(): string {
const account = this._account
return account ? `${account.name}@${account.authority}` : ''
}
public async doAction(contractName: string, actionName: string, authorization: string | string[], ...param: any[]) {
let eos = this.eos
if (!eos) return undefined
const options = {
authorization: typeof authorization === 'string' ? [authorization] : authorization
}
const contract = await eos.contract(contractName)
if (!contract) return undefined
const res = await contract[actionName].apply(window, param.concat(options))
return res
}
public async doSimpleAction(actionName: string, ...param: any[]) {
let res = undefined
if (this._config.defaultContract) {
res = await this.doAction(this._config.defaultContract, actionName, this.getAuthorization(), ...param)
}
return res
}
public async getTableRows(
table: string,
scope: string,
contractName?: string,
limit?: number,
lower_bound?: number,
table_key?: string
) {
if (!contractName) {
if (!this._config.defaultContract) return { rows: [], more: false }
contractName = this._config.defaultContract
}
try {
const param: any = {
code: contractName,
scope: scope,
table: table,
json: true,
lower_bound: lower_bound
}
limit && (param['limit'] = limit)
table_key && (param['table_key'] = table_key)
if (!this.eos) return { rows: [], more: false }
return await this.eos.getTableRows(param)
} catch (e) {
throw e
}
}
public async getAllTableRows(scope: string | number, tableName: string, table_key?: string, contractName?: string) {
if (!contractName) {
if (!this._config.defaultContract) return []
contractName = this._config.defaultContract
}
if (!scope) return []
const result = new Array<any>()
const limit = 10
let lower_bound = 0
while (true) {
const data = await this.getTableRows(tableName, scope.toString(), contractName, limit, lower_bound, table_key)
if (!data) break
if (data.rows && data.rows.length > 0) {
for (let i = 0; i < data.rows.length; i++) {
result.push(data.rows[i])
}
lower_bound += data.rows.length
if (!data.more) break
} else {
break
}
}
return result
}
public async getGlobalData() {
const res = await this.getTableRows('eosio', 'global', 'eosio')
if (res && res.rows && res.rows.length > 0) return res.rows[0]
return null
}
public async getRamPrice() {
const res = await this.getTableRows('eosio', 'rammarket', 'eosio')
if (res && res.rows && res.rows.length > 0) {
return (this.formatEos(res.rows[0].quote.balance) / this.formatEos(res.rows[0].base.balance)) * 1024
}
return 0
}
public async buyRam(ramAmount: number) {
try {
this.onContract(0)
const res = await this.doAction('eosio', 'buyrambytes', this.defaultAccount(), this.defaultAccount(), ramAmount)
this.onContract(1, res)
return res
} catch (e) {
this.handleError(e)
throw e
} finally {
this.onContract(3)
}
}
public async getNetCpuPrice() {
const res = await this.getAccountInfo()
let netPrice = 0
let cpuPrice = 0
if (res) {
// 1. 计算NET价格
// 抵押NET的EOS数量
let netBalance = res.net_weight / 10000
// NET贷款的总量
let netTotal = res.net_limit.max / 1024
// (netBalance / netTotal)获取到的是过去3天内的平均消耗量,除以3获取每天的平均消耗量,即价格
netPrice = netBalance / netTotal / 3
console.log(netBalance, netTotal, netPrice)
// 1. 计算CPU价格
// 抵押CPU的EOS数量
const cpuBalance = res.cpu_weight / 10000
// CPU贷款的总量
const cpuTotal = res.cpu_limit.max / 1024
// (cpuBalance / cpuTotal)获取到的是过去3天内的平均消耗量,除以3获取每天的平均消耗量,即价格
cpuPrice = cpuBalance / cpuTotal / 3
}
return {
netPrice: netPrice,
cpuPrice: cpuPrice
}
}
public async sellRam(ramAmount: number) {
try {
this.onContract(0)
const res = await this.doAction('eosio', 'sellram', this.defaultAccount(), ramAmount)
this.onContract(1, res)
return res
} catch (e) {
this.handleError(e)
throw e
} finally {
this.onContract(3)
}
}
// 抵押EOS购买NET、CPU
public async delegatebw(net_amount: number, cpu_amount: number) {
try {
this.onContract(0)
const res = await this.doAction(
'eosio',
'delegatebw',
this.defaultAccount(),
this.defaultAccount(),
`${net_amount.toFixed(4)} EOS`,
`${cpu_amount.toFixed(4)} EOS`,
0
)
this.onContract(1, res)
return res
} catch (e) {
this.handleError(e)
throw e
} finally {
this.onContract(3)
}
}
// 从NET、CPU资源中赎回EOS
public async undelegatebw(net_amount: number, cpu_amount: number) {
try {
this.onContract(0)
const res = await this.doAction(
'eosio',
'undelegatebw',
this.defaultAccount(),
this.defaultAccount(),
`${net_amount.toFixed(4)} EOS`,
`${cpu_amount.toFixed(4)} EOS`
)
this.onContract(1, res)
return res
} catch (e) {
this.handleError(e)
throw e
} finally {
this.onContract(3)
}
}
private handleError(e: any) {
if (!e) return
if (typeof e === 'string') {
try {
const obj = JSON.parse(e)
typeof obj === 'object' && obj && (e = obj)
} catch (e) {
// e
}
}
e.error && e.error.details
? this.onError(base.ErrorCode.TranSactionError, e)
: this.onError(base.ErrorCode.UnknowError, e)
}
}
}