Account

Account extends AddrAccount

使用私钥生成 Account 实例。除包含 AddrAccount 的所有功能外,还可以快速发送交易,以及各种签名相关操作。

安装

npm install @vite/vitejs-account --save
yarn add @vite/vitejs-account

引入

import { account } from '@vite/vitejs';
// Or
import account from '@vite/vitejs-account';
const { account } = require('@vite/vitejs-account');

Constructor

Account extends AddrAccount

  • Constructor Parameters:
    • __namedParameters : object
      • privateKey? : Hex 私钥
      • address?: Address 地址
      • client : Client client 实例
    • __namedParameters? : object Default { autoPow: false, usePledgeQuota: true }
      • autoPow?: boolean 配额不足时,发送交易是否默认运行 PoW Default false
      • usePledgeQuota? : boolean 检查是否需要运行 PoW 时,是否优先使用配额 Default true
privateKey address 是否可调用全部方法 是否自动生成私钥 是否自动生成地址 描述
-- --
-- --
-- -- -- -- 只能调用不使用私钥的方法,否则报错
-- -- 私钥和地址不匹配则报错

Example

Notice

具体 API 调用,请参阅文档

const { WS_RPC } = require('@vite/vitejs-ws');
const { client, account, utils, constant } = require('@vite/vitejs');
let { Vite_TokenId } = constant;
let provider = new WS_RPC("ws://example.com");
let myClient = new client(provider);
let myAccount = new account({
    client: myClient,
    privateKey: 'your privateKey'   // Notice: privateKey 不是助记词,一个地址对应一个 privateKey
});
// 查询余额
myAccount.getBalance().then((result) => {
    console.log(result);
}).catch((err) => {
    console.warn(err);
});
// 请确保您的账户中有余额。因为发送交易时需要配额,可以选择首先抵押配额
myAccount.getQuota({
    toAddress: myAccount.address,
    tokenId: Vite_TokenId,
    amount: '134000000000000000000' // 至少 134 Vite
}).then((accountBlock) => {
    console.log(accountBlock);
});
// 获取交易列表
myAccount.getTxList({
    index: 0,
    pageCount: 50
}).then((data) => {
    let txList = data.list || [];
    console.log(txList);
});
// 发送交易
myAccount.sendTx({
    toAddress: 'Your toAddress',
    amount: '10000000000000000000',    // 10Vite + 18个0
    tokenId: Vite_TokenId
}).then((accountBlock) => {
    console.log(accountBlock);
}).catch((err) => {
    console.log(err);
});
// 获取在途交易列表
myAccount.getOnroadBlocks({
    index: 0,
    pageCount: 10
}).then((data) => {
    if (!data || !data.length) {
        console.log('No onroad');
        return;
    }
    // 当发现在途时,你可以开始接收交易
    myAccount.receiveTx({
        fromBlockHash: data[0].hash
    }).then((accountBlock) => {
        console.log(accountBlock);
    });
});

Properties

Name Type Description
privateKey string 私钥
publicKey string 公钥
address Address 地址
balance object 余额
autoPow boolean 是否自动运行 PoW
usePledgeQuota boolean 检查 PoW 时,是否优先使用配额

Methods

getBlock

Refer to addrAccount.getblock

clearPrivateKey

冻结账户并且清空私钥

setPrivateKey

  • Parameters
    • privateKey : string

getPublicKey

  • Return:
    • publicKey : Uint8Array with 32-byte public key

sign

  • Parameters

    • hexStr : Hex 需要签名的 Hex-string
  • Return:

    • signature : string 签名后的信息

signAccountBlock

  • Parameters

    • accountBlock : AccountBlock
  • Return:

    • accountBlock : AccountBlock 签名后的 accountBlock

activate

激活账户

  1. 轮询账户余额 => 自动更新 balance 属性;
  2. 当发现在途时,会启动自动接收交易任务;在途接收完成,任务停止。
  • Parameters
    • intervals : number 轮询间隔 Default 2000ms
    • autoPow?: boolean 发送交易配额不足时,是否默认运行 PoW Default this.autoPow
    • usePledgeQuota? : boolean 检查是否需要运行 PoW 时,是否优先使用配额 Default this.usePledgeQuota

freeze

冻结账户,停止激活状态

  1. 停止轮询余额
  2. 停止自动接收交易任务

autoReceiveTx

启动自动接收交易任务

  • Parameters
    • intervals : number 轮询间隔 Default 2000ms
    • autoPow?: boolean 配额不足时,是否默认运行 PoW Default this.autoPow
    • usePledgeQuota? : boolean 检查是否需要运行 PoW 时,是否优先使用配额 Default this.usePledgeQuota

stopAutoReceiveTx

停止自动接收交易任务

sendRawTx

发送原始交易。 client.sendTx

  • Parameters

    • accountBlock 规范后的 accountBlock(可以不包含 accountAddress 字段)
  • Return

    • Promise< AccountBlock >

sendAutoPowRawTx

当没有配额时,自动运行 PoW 发送原始交易。 client.sendAutoPowTx

  • Parameters

    • accountBlock 规范后的 accountBlock(可以不包含 accountAddress 字段)
    • usePledgeQuota : boolean 是否优先使用配额,Default this.usePledgeQuota
  • Return

    • Promise< AccountBlock >

sendPowTx

发送一笔交易,传入不同阶段的函数回调,可用于执行自定义的用户行为,或者打断交易流程。

LifeCycle

  • start
    1. Get block. this.getBlock[methodName](...params)
  • beforeCheckPow
    1. beforeCheckPow ? beforeCheckPow() : go to 2
    2. Check PoW. tx_calcPoWDifficulty
  • checkPowDone
    1. The check results, if need PoW go to 2; else go to powDone 1.
    2. beforePow ? beforePow() : go to 3
    3. next(isReject = false) If need PoW go to 4; else break.
    4. Run PoW.
  • powDone
    1. beforeSignTx ? beforeSignTx() : go to 2
    2. next(isReject = false) If need sign Tx go to 3; else break.
    3. Sign TX.
  • signDone
    1. beforeSendTx ? beforeSendTx() : go to 2
    2. next(isReject = false) If need send Tx go to 3; else break.
    3. Send TX.
  • finish
  • Parameters

    • __namedParameters : object
      • methodName : string this.getBlock 中的方法名称
      • params : Array 传入 this.getBlock[methodName] 中的参数
      • beforeCheckPow : Function
      • beforePow : Function
      • beforeSignTx? : Function
      • beforeSendTx : Function
  • Return

    • Promise< { lifeCycle, accountBlock, checkPowResult } >
  • BeforeCheckPow

    • Parameters

      • accountBlock: AccountBlock 不同类型的 accountBlock(无 PoW,无签名)
      • next : Function
    • Return

      • next(<usePledgeQuota: boolean>) 是否优先使用配额 Default true
  • BeforePow

    • Parameters

      • accountBlock: AccountBlock 不同类型的 accountBlock(无 PoW,无签名)
      • checkPowResult: <difficulty, quota>
      • next : Function
    • Return

      • next(<isReject: boolean>) 是否打断交易流程. Default false
  • beforeSignTx

    • Parameters

      • accountBlock: AccountBlock 在检查 PoW(并可能运行 PoW)后的 accountBlock(无签名)
      • checkPowResult: <difficulty, quota>
      • next : Function
    • Return

      • next(<isReject: boolean>) 是否打断交易流程. Default false
  • BeforeSendTx

    • Parameters

      • accountBlock: AccountBlock 签名后的 accountBlock
      • checkPowResult: <difficulty, quota>
      • next : Function
    • Return

      • next(<isReject: boolean>) 是否打断交易流程. Default false

next

使用 next(true) 打断流程,会默认返回 Promise.resolve({ lifeCycle, accountBlock, checkPowResult });

若希望自定义行为,可以 return Promise.reject() || new Promise((res, rej) => {})

  • Example
// ...
const result = await myAccount.sendPowTx({
    methodName: 'asyncSendTx',
    params: [{
        toAddress: myAccount.address,
        tokenId: Vite_TokenId,
        amount: '100'
    }],
    beforeCheckPow: (accountBlock, next) => {
        console.log('[beforeCheckPow]', accountBlock);
        return next();
    },
    beforePow: (accountBlock, checkPowResult, next) => {
        console.log('[beforePow]', accountBlock, checkPowResult);
        return next();
    },
    beforeSendTx: (accountBlock, checkPowResult, next) => {
        console.log('[beforeSendTx]', accountBlock, checkPowResult);
        return next();
    }
});
console.log('[LOG] SendTx', result, '\n');
return result;
// ...
const result = await myAccount.sendPowTx({
    methodName: 'asyncSendTx',
    params: [{
        toAddress: myAccount.address,
        tokenId: Vite_TokenId,
        amount: '100'
    }],
    beforeCheckPow: (accountBlock, next) => {
        console.log('[beforeCheckPow]', accountBlock);
        // Break
        return next(true);
    }
});
console.log('[LOG] SendTx', result, '\n');
return result;
// ...
const result = await myAccount.sendPowTx({
    methodName: 'asyncSendTx',
    params: [{
        toAddress: myAccount.address,
        tokenId: Vite_TokenId,
        amount: '100'
    }],
    beforePow: (accountBlock, checkPowResult, next) => {
        console.log('[beforePow]', accountBlock, checkPowResult);
        if (checkPowResult.diffculty) {
            // Break
            return Promise.reject();
        }
        return next();
    },
});
console.log('[LOG] SendTx', result, '\n');
return result;

快速发送交易

Account 会自动从 client.builtinTxBlock 中获取生成块方法并进行封装。

实现方式

如果想自行实现此方法,可参照此调用逻辑进行封装。

  1. accountBlock.accountAddress = this.address
  2. 通过 block 方法获取到合法块
  3. 签名并发送 AccountBlock
  • Code
for (const key in this._client.builtinTxBlock) {
    if (key === '_client' || key.endsWith('Block')) {
        continue;
    }
    let _key = key;
    if (_key.startsWith('async')) {
        _key = _key.replace('async', '');
        _key = _key[0].toLocaleLowerCase() + _key.slice(1);
    }
    this[_key] = async (params, autoPow?, usePledgeQuota?) => {
        params.accountAddress = this.address;
        const block = await this.getBlock[key](params);
        const _autoPow = autoPow === true || autoPow === false ? autoPow : !!this.autoPow;
        if (!_autoPow) {
            return this.sendRawTx(accountBlock);
        }
        return this.sendAutoPowRawTx(accountBlock, usePledgeQuota);
    };
}

调用方式

  • Parameters

    • params : Array<accountBlock, requestType> accountBlock(可以不包含 accountAddress)
    • autoPow? : boolean 是否自动运行 PoW。Default this.autoPow
    • usePledgeQuota? : boolean 是否优先使用配额。Default this.usePledgeQuota
  • Return

    • Promise< AccountBlock >
  • Example

// ....
const result = await myAccount.SBPreg({
    nodeName: 'TEST_NODE',
    toAddress: myAccount.address,
    amount: '100000000000000000000000',
    tokenId: Vite_TokenId
});
console.log('[LOG] SBPreg', result, '\n');
return result;