near-workspaces
Version:
Write tests in TypeScript/JavaScript to run in a controlled NEAR Sandbox local environment.
204 lines • 8.13 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainnetRpc = exports.TestnetRpc = exports.JsonRpcProvider = void 0;
// eslint-disable unicorn/no-object-as-default-parameter
const buffer_1 = require("buffer");
const process_1 = __importDefault(require("process"));
const transaction_1 = require("near-api-js/lib/transaction");
const types_1 = require("./types");
const OPTIMISTIC = { finality: 'optimistic' };
/**
* Extends the main provider class in near-api-js, adding more methods for
* interacting with an endpoint.
*/
class JsonRpcProvider extends types_1.JSONRpc {
/**
* Create a JsonRpcProvider from config or rpcAddr
* @param config rpc endpoint URL or a configuration that includes one.
* @returns JsonRpcProvider
*/
static from(config) {
const url = typeof config === 'string' ? config : config.rpcAddr;
if (!this.providers.has(url)) {
this.providers.set(url, new JsonRpcProvider({ url }));
}
return this.providers.get(url);
}
static fromNetwork(network) {
switch (network) {
case 'mainnet': {
return process_1.default.env.NEAR_CLI_MAINNET_RPC_SERVER_URL
? JsonRpcProvider.from(process_1.default.env.NEAR_CLI_MAINNET_RPC_SERVER_URL)
: exports.MainnetRpc;
}
case 'testnet': {
return process_1.default.env.NEAR_CLI_TESTNET_RPC_SERVER_URL
? JsonRpcProvider.from(process_1.default.env.NEAR_CLI_TESTNET_RPC_SERVER_URL)
: exports.TestnetRpc;
}
default: {
throw new TypeError('Invalid network only mainnet or testnet');
}
}
}
static providers = new Map();
/**
* Download the binary of a given contract.
* @param accountId contract account
* @returns Buffer of Wasm binary
*/
async viewCode(accountId, blockQuery) {
return buffer_1.Buffer.from(await this.viewCodeRaw(accountId, blockQuery), 'base64');
}
/**
* Download the binary of a given contract.
* @param accountId contract account
* @returns Base64 string of Wasm binary
*/
async viewCodeRaw(accountId, blockQuery = OPTIMISTIC) {
const { code_base64: codeBase64 } = await this.query({
request_type: 'view_code',
account_id: accountId,
...blockQuery,
});
return codeBase64;
}
async viewAccount(accountId, blockQuery = OPTIMISTIC) {
return this.query({
request_type: 'view_account',
account_id: accountId,
...blockQuery,
});
}
async accountExists(accountId, blockQuery) {
try {
await this.viewAccount(accountId, blockQuery);
return true;
}
catch {
return false;
}
}
async viewAccessKey(accountId, publicKey, blockQuery = OPTIMISTIC) {
return this.query({
request_type: 'view_access_key',
account_id: accountId,
public_key: typeof publicKey === 'string' ? publicKey : publicKey.toString(),
...blockQuery,
});
}
async viewAccessKeys(accountId, blockQuery = OPTIMISTIC) {
return this.query({
request_type: 'view_access_key_list',
account_id: accountId,
...blockQuery,
});
}
async protocolConfig(blockQuery = OPTIMISTIC) {
// @ts-expect-error Bad type
return this.experimental_protocolConfig(blockQuery);
}
async accountBalance(accountId, blockQuery) {
const config = await this.protocolConfig(blockQuery);
const state = await this.viewAccount(accountId, blockQuery);
const costPerByte = BigInt(config.runtime_config.storage_amount_per_byte);
const stateStaked = BigInt(state.storage_usage) * costPerByte;
const staked = BigInt(state.locked);
const total = BigInt(state.amount) + staked;
// eslint-disable-next-line unicorn/prefer-math-min-max
const available = total - (staked > stateStaked ? staked : stateStaked);
return {
total: total.toString(),
stateStaked: stateStaked.toString(),
staked: staked.toString(),
available: available.toString(),
};
}
async viewCall(accountId, methodName, args, blockQuery) {
const argsBuffer = (0, transaction_1.stringifyJsonOrBytes)(args);
return this.viewCallRaw(accountId, methodName, argsBuffer.toString('base64'), blockQuery);
}
/**
* Get full response from RPC about result of view method
* @param accountId
* @param methodName
* @param args Base64 encoded string
* @param blockQuery
* @returns
*/
async viewCallRaw(accountId, methodName, args, blockQuery = OPTIMISTIC) {
return this.query({
request_type: 'call_function',
account_id: accountId,
method_name: methodName,
args_base64: args,
...blockQuery,
});
}
/**
* Download the state of a contract given a prefix of a key.
*
* @param accountId contract account to lookup
* @param prefix string or byte prefix of keys to loodup
* @param blockQuery state at what block, defaults to most recent final block
* @returns raw RPC response
*/
async viewState(accountId, prefix, blockQuery) {
const values = await this.viewStateRaw(accountId, prefix, blockQuery);
return values.map(({ key, value }) => ({
key: buffer_1.Buffer.from(key, 'base64'),
value: buffer_1.Buffer.from(value, 'base64'),
}));
}
/**
* Download the state of a contract given a prefix of a key without decoding from base64.
*
* @param accountId contract account to lookup
* @param prefix string or byte prefix of keys to loodup
* @param blockQuery state at what block, defaults to most recent final block
* @returns raw RPC response
*/
async viewStateRaw(accountId, prefix, blockQuery) {
const { values } = await this.query({
request_type: 'view_state',
...(blockQuery ?? { finality: 'optimistic' }),
account_id: accountId,
prefix_base64: buffer_1.Buffer.from(prefix).toString('base64'),
});
return values;
}
/**
* Updates records without using a transaction.
* Note: only avaialable on Sandbox endpoints.
* @param records
* @returns Promise<Empty>
*/
async patchStateRecords(records) {
return this.sendJsonRpc('sandbox_patch_state', records);
}
/**
* Fast forward to a point in the future. The delta block height is supplied to tell the
* network to advanced a certain amount of blocks. This comes with the advantage only having
* to wait a fraction of the time it takes to produce the same number of blocks.
*
* Estimate as to how long it takes: if our delta_height crosses `X` epochs, then it would
* roughly take `X * 5` milliseconds for the fast forward request to be processed.
*
* Note: This is not to be confused with speeding up the current in-flight transactions;
* the state being forwarded in this case refers to time-related state (the block height, timestamp and epoch).
* @param deltaHeight
* @returns Promise<Empty>
*/
async fastForward(deltaHeight) {
return this.sendJsonRpc('sandbox_fast_forward', { delta_height: deltaHeight });
}
}
exports.JsonRpcProvider = JsonRpcProvider;
// eslint-disable-next-line @typescript-eslint/naming-convention
exports.TestnetRpc = JsonRpcProvider.from(types_1.TESTNET_RPC_ADDR);
// eslint-disable-next-line @typescript-eslint/naming-convention
exports.MainnetRpc = JsonRpcProvider.from(types_1.MAINNET_RPC_ADDR);
//# sourceMappingURL=jsonrpc.js.map
;