@yubing744/rooch-sdk
Version:
293 lines (292 loc) • 8.92 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var account_exports = {};
__export(account_exports, {
Account: () => Account
});
module.exports = __toCommonJS(account_exports);
var import_constants = require("../constants");
var import_auth = require("../auth");
var import_bcs = require("../types/bcs");
var import_mod = require("../generated/runtime/rooch_types/mod");
var import_utils = require("../utils");
var import_keypairs = require("../utils/keypairs");
const SCOPE_LENGTH = 3;
const SCOPE_MODULE_ADDRESSS = 0;
const SCOPE_MODULE_NAMES = 1;
const SCOPE_FUNCTION_NAMES = 2;
class Account {
constructor(client, address, authorizer) {
this.client = client;
this.address = address;
this.authorizer = authorizer;
}
async makeAuth(tsData) {
const payload = (() => {
const se = new import_bcs.BcsSerializer();
tsData.serialize(se);
return se.getBytes();
})();
return this.authorizer.auth(payload);
}
parseStateToSessionKey(data) {
const result = new Array();
for (const state of data.data) {
const moveValue = state?.state.decoded_value;
if (moveValue) {
const val = moveValue.value;
result.push({
authentication_key: val.authentication_key,
scopes: this.parseScopes(val.scopes),
create_time: parseInt(val.create_time),
last_active_time: parseInt(val.last_active_time),
max_inactive_interval: parseInt(val.max_inactive_interval)
});
}
}
return result;
}
parseScopes(data) {
const result = new Array();
for (const scope of data) {
result.push(`${scope.module_name}::${scope.module_address}::${scope.function_name}`);
}
return result;
}
async getSequenceNumber() {
const resp = await this.client.executeViewFunction({
funcId: "0x3::account::sequence_number",
tyArgs: [],
args: [
{
type: "Address",
value: this.address
}
]
});
if (resp && resp.return_values) {
return resp.return_values[0].decoded_value;
}
return 0;
}
/**
* Get account address
*/
getAddress() {
return this.address;
}
/**
* Run move function by current account
*
* @param funcId FunctionId the function like '0x3::empty::empty'
* @param tyArgs Generic parameter list
* @param args parameter list
* @param opts Call option
*/
async runFunction(funcId, tyArgs, args, opts) {
const number = await this.getSequenceNumber();
const bcsArgs = args.map((arg) => (0, import_utils.encodeArg)(arg));
const scriptFunction = (0, import_utils.encodeFunctionCall)(funcId, tyArgs, bcsArgs);
const txData = new import_mod.RoochTransactionData(
new import_mod.AccountAddress((0, import_utils.addressToListTuple)(this.address)),
BigInt(number),
BigInt(this.client.getChainId()),
BigInt(opts.maxGasAmount ?? import_constants.DEFAULT_MAX_GAS_AMOUNT),
scriptFunction
);
const authResult = await this.makeAuth(txData);
const auth = new import_mod.Authenticator(
BigInt(authResult.scheme),
(0, import_utils.uint8Array2SeqNumber)(authResult.payload)
);
const ts = new import_mod.RoochTransaction(txData, auth);
const payload = (() => {
const se = new import_bcs.BcsSerializer();
ts.serialize(se);
return se.getBytes();
})();
return this.client.sendRawTransaction(payload);
}
async createSessionAccount(scope, maxInactiveInterval, opts) {
const kp = import_keypairs.Ed25519Keypair.generate();
await this.registerSessionKey(
kp.getPublicKey().toRoochAddress(),
scope,
maxInactiveInterval,
opts
);
const auth = new import_auth.PrivateKeyAuth(kp);
return new Account(this.client, this.address, auth);
}
async registerSessionKey(authKey, scopes, maxInactiveInterval, opts) {
const [scopeModuleAddresss, scopeModuleNames, scopeFunctionNames] = scopes.map((scope) => {
const parts = scope.split("::");
if (parts.length !== SCOPE_LENGTH) {
throw new Error("invalid scope");
}
const scopeModuleAddress = parts[SCOPE_MODULE_NAMES];
const scopeModuleName = parts[SCOPE_MODULE_ADDRESSS];
const scopeFunctionName = parts[SCOPE_FUNCTION_NAMES];
return [scopeModuleAddress, scopeModuleName, scopeFunctionName];
}).reduce(
(acc, val) => {
acc[0].push(val[SCOPE_MODULE_NAMES]);
acc[1].push(val[SCOPE_MODULE_ADDRESSS]);
acc[2].push(val[SCOPE_FUNCTION_NAMES]);
return acc;
},
[[], [], []]
);
await this.runFunction(
"0x3::session_key::create_session_key_with_multi_scope_entry",
[],
[
{
type: { Vector: "U8" },
value: (0, import_utils.addressToSeqNumber)(authKey)
},
{
type: { Vector: "Address" },
value: scopeModuleAddresss
},
{
type: { Vector: "Ascii" },
value: scopeModuleNames
},
{
type: { Vector: "Ascii" },
value: scopeFunctionNames
},
{
type: "U64",
value: BigInt(maxInactiveInterval)
}
],
opts || {
maxGasAmount: 1e8
}
);
}
/**
* Remove session key
*
* @param authKey
* @param opts
*/
async removeSessionKey(authKey, opts) {
return await this.runFunction(
"0x3::session_key::remove_session_key_entry",
[],
[
{
type: { Vector: "U8" },
value: (0, import_utils.addressToSeqNumber)(authKey)
}
],
opts || {
maxGasAmount: 1e8
}
);
}
/**
* Query account's sessionKey
*
* @param cursor The page cursor
* @param limit The page limit
*/
async querySessionKeys(cursor, limit) {
const accessPath = `/resource/${this.address}/0x3::session_key::SessionKeys`;
const state = await this.client.getStates(accessPath);
if (state) {
const stateView = state;
const tableId = stateView[0].value;
const accessPath2 = `/table/${tableId}`;
const pageView = await this.client.listStates({
accessPath: accessPath2,
cursor,
limit
});
return {
data: this.parseStateToSessionKey(pageView),
nextCursor: pageView.next_cursor,
hasNextPage: pageView.has_next_page
};
}
throw new Error("not found state");
}
/**
* Check session key whether expired
*
* @param authKey the auth key
*/
async isSessionKeyExpired(authKey) {
const result = await this.client.executeViewFunction({
funcId: "0x3::session_key::is_expired_session_key",
tyArgs: [],
args: [
{
type: "Address",
value: this.address
},
{
type: { Vector: "U8" },
value: (0, import_utils.addressToSeqNumber)(authKey)
}
]
});
if (result && result.vm_status !== "Executed") {
throw new Error("view 0x3::session_key::is_expired_session_key fail");
}
return result.return_values[0].decoded_value;
}
async gasCoinBalance() {
const result = await this.client.executeViewFunction({
funcId: "0x3::gas_coin::balance",
tyArgs: [],
args: [
{
type: "Address",
value: this.getAddress()
}
]
});
if (result && result.vm_status !== "Executed") {
throw new Error("view 0x3::gas_coin::balance fail");
}
return BigInt(result.return_values[0].decoded_value);
}
async coinBalance(coinType) {
const structType = (0, import_utils.encodeStructTypeTag)(coinType);
const result = await this.client.executeViewFunction({
funcId: "0x3::account_coin_store::balance",
tyArgs: [structType],
args: [
{
type: "Address",
value: this.getAddress()
}
]
});
if (result && result.vm_status !== "Executed") {
throw new Error("view 0x3::account_coin_store::balance fail");
}
return BigInt(result.return_values[0].decoded_value);
}
}
//# sourceMappingURL=account.js.map