@mysten/sui
Version:
Sui TypeScript API(Work in Progress)
700 lines (699 loc) • 21.2 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 client_exports = {};
__export(client_exports, {
SuiClient: () => SuiClient,
isSuiClient: () => isSuiClient
});
module.exports = __toCommonJS(client_exports);
var import_bcs = require("@mysten/bcs");
var import_client = require("../experimental/client.js");
var import_jsonRPC = require("../experimental/transports/jsonRPC.js");
var import_transactions = require("../transactions/index.js");
var import_sui_types = require("../utils/sui-types.js");
var import_suins = require("../utils/suins.js");
var import_http_transport = require("./http-transport.js");
const SUI_CLIENT_BRAND = Symbol.for("@mysten/SuiClient");
function isSuiClient(client) {
return typeof client === "object" && client !== null && client[SUI_CLIENT_BRAND] === true;
}
class SuiClient extends import_client.Experimental_BaseClient {
/**
* Establish a connection to a Sui RPC endpoint
*
* @param options configuration options for the API Client
*/
constructor(options) {
super({ network: options.network ?? "unknown" });
this.core = new import_jsonRPC.JSONRpcTransport(this);
this.jsonRpc = this;
this.transport = options.transport ?? new import_http_transport.SuiHTTPTransport({ url: options.url });
}
get [SUI_CLIENT_BRAND]() {
return true;
}
async getRpcApiVersion({ signal } = {}) {
const resp = await this.transport.request({
method: "rpc.discover",
params: [],
signal
});
return resp.info.version;
}
/**
* Get all Coin<`coin_type`> objects owned by an address.
*/
async getCoins(input) {
if (!input.owner || !(0, import_sui_types.isValidSuiAddress)((0, import_sui_types.normalizeSuiAddress)(input.owner))) {
throw new Error("Invalid Sui address");
}
return await this.transport.request({
method: "suix_getCoins",
params: [input.owner, input.coinType, input.cursor, input.limit],
signal: input.signal
});
}
/**
* Get all Coin objects owned by an address.
*/
async getAllCoins(input) {
if (!input.owner || !(0, import_sui_types.isValidSuiAddress)((0, import_sui_types.normalizeSuiAddress)(input.owner))) {
throw new Error("Invalid Sui address");
}
return await this.transport.request({
method: "suix_getAllCoins",
params: [input.owner, input.cursor, input.limit],
signal: input.signal
});
}
/**
* Get the total coin balance for one coin type, owned by the address owner.
*/
async getBalance(input) {
if (!input.owner || !(0, import_sui_types.isValidSuiAddress)((0, import_sui_types.normalizeSuiAddress)(input.owner))) {
throw new Error("Invalid Sui address");
}
return await this.transport.request({
method: "suix_getBalance",
params: [input.owner, input.coinType],
signal: input.signal
});
}
/**
* Get the total coin balance for all coin types, owned by the address owner.
*/
async getAllBalances(input) {
if (!input.owner || !(0, import_sui_types.isValidSuiAddress)((0, import_sui_types.normalizeSuiAddress)(input.owner))) {
throw new Error("Invalid Sui address");
}
return await this.transport.request({
method: "suix_getAllBalances",
params: [input.owner],
signal: input.signal
});
}
/**
* Fetch CoinMetadata for a given coin type
*/
async getCoinMetadata(input) {
return await this.transport.request({
method: "suix_getCoinMetadata",
params: [input.coinType],
signal: input.signal
});
}
/**
* Fetch total supply for a coin
*/
async getTotalSupply(input) {
return await this.transport.request({
method: "suix_getTotalSupply",
params: [input.coinType],
signal: input.signal
});
}
/**
* Invoke any RPC method
* @param method the method to be invoked
* @param args the arguments to be passed to the RPC request
*/
async call(method, params, { signal } = {}) {
return await this.transport.request({ method, params, signal });
}
/**
* Get Move function argument types like read, write and full access
*/
async getMoveFunctionArgTypes(input) {
return await this.transport.request({
method: "sui_getMoveFunctionArgTypes",
params: [input.package, input.module, input.function],
signal: input.signal
});
}
/**
* Get a map from module name to
* structured representations of Move modules
*/
async getNormalizedMoveModulesByPackage(input) {
return await this.transport.request({
method: "sui_getNormalizedMoveModulesByPackage",
params: [input.package],
signal: input.signal
});
}
/**
* Get a structured representation of Move module
*/
async getNormalizedMoveModule(input) {
return await this.transport.request({
method: "sui_getNormalizedMoveModule",
params: [input.package, input.module],
signal: input.signal
});
}
/**
* Get a structured representation of Move function
*/
async getNormalizedMoveFunction(input) {
return await this.transport.request({
method: "sui_getNormalizedMoveFunction",
params: [input.package, input.module, input.function],
signal: input.signal
});
}
/**
* Get a structured representation of Move struct
*/
async getNormalizedMoveStruct(input) {
return await this.transport.request({
method: "sui_getNormalizedMoveStruct",
params: [input.package, input.module, input.struct],
signal: input.signal
});
}
/**
* Get all objects owned by an address
*/
async getOwnedObjects(input) {
if (!input.owner || !(0, import_sui_types.isValidSuiAddress)((0, import_sui_types.normalizeSuiAddress)(input.owner))) {
throw new Error("Invalid Sui address");
}
return await this.transport.request({
method: "suix_getOwnedObjects",
params: [
input.owner,
{
filter: input.filter,
options: input.options
},
input.cursor,
input.limit
],
signal: input.signal
});
}
/**
* Get details about an object
*/
async getObject(input) {
if (!input.id || !(0, import_sui_types.isValidSuiObjectId)((0, import_sui_types.normalizeSuiObjectId)(input.id))) {
throw new Error("Invalid Sui Object id");
}
return await this.transport.request({
method: "sui_getObject",
params: [input.id, input.options],
signal: input.signal
});
}
async tryGetPastObject(input) {
return await this.transport.request({
method: "sui_tryGetPastObject",
params: [input.id, input.version, input.options],
signal: input.signal
});
}
/**
* Batch get details about a list of objects. If any of the object ids are duplicates the call will fail
*/
async multiGetObjects(input) {
input.ids.forEach((id) => {
if (!id || !(0, import_sui_types.isValidSuiObjectId)((0, import_sui_types.normalizeSuiObjectId)(id))) {
throw new Error(`Invalid Sui Object id ${id}`);
}
});
const hasDuplicates = input.ids.length !== new Set(input.ids).size;
if (hasDuplicates) {
throw new Error(`Duplicate object ids in batch call ${input.ids}`);
}
return await this.transport.request({
method: "sui_multiGetObjects",
params: [input.ids, input.options],
signal: input.signal
});
}
/**
* Get transaction blocks for a given query criteria
*/
async queryTransactionBlocks(input) {
return await this.transport.request({
method: "suix_queryTransactionBlocks",
params: [
{
filter: input.filter,
options: input.options
},
input.cursor,
input.limit,
(input.order || "descending") === "descending"
],
signal: input.signal
});
}
async getTransactionBlock(input) {
if (!(0, import_sui_types.isValidTransactionDigest)(input.digest)) {
throw new Error("Invalid Transaction digest");
}
return await this.transport.request({
method: "sui_getTransactionBlock",
params: [input.digest, input.options],
signal: input.signal
});
}
async multiGetTransactionBlocks(input) {
input.digests.forEach((d) => {
if (!(0, import_sui_types.isValidTransactionDigest)(d)) {
throw new Error(`Invalid Transaction digest ${d}`);
}
});
const hasDuplicates = input.digests.length !== new Set(input.digests).size;
if (hasDuplicates) {
throw new Error(`Duplicate digests in batch call ${input.digests}`);
}
return await this.transport.request({
method: "sui_multiGetTransactionBlocks",
params: [input.digests, input.options],
signal: input.signal
});
}
async executeTransactionBlock({
transactionBlock,
signature,
options,
requestType,
signal
}) {
const result = await this.transport.request({
method: "sui_executeTransactionBlock",
params: [
typeof transactionBlock === "string" ? transactionBlock : (0, import_bcs.toBase64)(transactionBlock),
Array.isArray(signature) ? signature : [signature],
options
],
signal
});
if (requestType === "WaitForLocalExecution") {
try {
await this.waitForTransaction({
digest: result.digest
});
} catch (_) {
}
}
return result;
}
async signAndExecuteTransaction({
transaction,
signer,
...input
}) {
let transactionBytes;
if (transaction instanceof Uint8Array) {
transactionBytes = transaction;
} else {
transaction.setSenderIfNotSet(signer.toSuiAddress());
transactionBytes = await transaction.build({ client: this });
}
const { signature, bytes } = await signer.signTransaction(transactionBytes);
return this.executeTransactionBlock({
transactionBlock: bytes,
signature,
...input
});
}
/**
* Get total number of transactions
*/
async getTotalTransactionBlocks({ signal } = {}) {
const resp = await this.transport.request({
method: "sui_getTotalTransactionBlocks",
params: [],
signal
});
return BigInt(resp);
}
/**
* Getting the reference gas price for the network
*/
async getReferenceGasPrice({ signal } = {}) {
const resp = await this.transport.request({
method: "suix_getReferenceGasPrice",
params: [],
signal
});
return BigInt(resp);
}
/**
* Return the delegated stakes for an address
*/
async getStakes(input) {
if (!input.owner || !(0, import_sui_types.isValidSuiAddress)((0, import_sui_types.normalizeSuiAddress)(input.owner))) {
throw new Error("Invalid Sui address");
}
return await this.transport.request({
method: "suix_getStakes",
params: [input.owner],
signal: input.signal
});
}
/**
* Return the delegated stakes queried by id.
*/
async getStakesByIds(input) {
input.stakedSuiIds.forEach((id) => {
if (!id || !(0, import_sui_types.isValidSuiObjectId)((0, import_sui_types.normalizeSuiObjectId)(id))) {
throw new Error(`Invalid Sui Stake id ${id}`);
}
});
return await this.transport.request({
method: "suix_getStakesByIds",
params: [input.stakedSuiIds],
signal: input.signal
});
}
/**
* Return the latest system state content.
*/
async getLatestSuiSystemState({
signal
} = {}) {
return await this.transport.request({
method: "suix_getLatestSuiSystemState",
params: [],
signal
});
}
/**
* Get events for a given query criteria
*/
async queryEvents(input) {
return await this.transport.request({
method: "suix_queryEvents",
params: [
input.query,
input.cursor,
input.limit,
(input.order || "descending") === "descending"
],
signal: input.signal
});
}
/**
* Subscribe to get notifications whenever an event matching the filter occurs
*
* @deprecated
*/
async subscribeEvent(input) {
return this.transport.subscribe({
method: "suix_subscribeEvent",
unsubscribe: "suix_unsubscribeEvent",
params: [input.filter],
onMessage: input.onMessage,
signal: input.signal
});
}
/**
* @deprecated
*/
async subscribeTransaction(input) {
return this.transport.subscribe({
method: "suix_subscribeTransaction",
unsubscribe: "suix_unsubscribeTransaction",
params: [input.filter],
onMessage: input.onMessage,
signal: input.signal
});
}
/**
* Runs the transaction block in dev-inspect mode. Which allows for nearly any
* transaction (or Move call) with any arguments. Detailed results are
* provided, including both the transaction effects and any return values.
*/
async devInspectTransactionBlock(input) {
let devInspectTxBytes;
if ((0, import_transactions.isTransaction)(input.transactionBlock)) {
input.transactionBlock.setSenderIfNotSet(input.sender);
devInspectTxBytes = (0, import_bcs.toBase64)(
await input.transactionBlock.build({
client: this,
onlyTransactionKind: true
})
);
} else if (typeof input.transactionBlock === "string") {
devInspectTxBytes = input.transactionBlock;
} else if (input.transactionBlock instanceof Uint8Array) {
devInspectTxBytes = (0, import_bcs.toBase64)(input.transactionBlock);
} else {
throw new Error("Unknown transaction block format.");
}
input.signal?.throwIfAborted();
return await this.transport.request({
method: "sui_devInspectTransactionBlock",
params: [input.sender, devInspectTxBytes, input.gasPrice?.toString(), input.epoch],
signal: input.signal
});
}
/**
* Dry run a transaction block and return the result.
*/
async dryRunTransactionBlock(input) {
return await this.transport.request({
method: "sui_dryRunTransactionBlock",
params: [
typeof input.transactionBlock === "string" ? input.transactionBlock : (0, import_bcs.toBase64)(input.transactionBlock)
]
});
}
/**
* Return the list of dynamic field objects owned by an object
*/
async getDynamicFields(input) {
if (!input.parentId || !(0, import_sui_types.isValidSuiObjectId)((0, import_sui_types.normalizeSuiObjectId)(input.parentId))) {
throw new Error("Invalid Sui Object id");
}
return await this.transport.request({
method: "suix_getDynamicFields",
params: [input.parentId, input.cursor, input.limit],
signal: input.signal
});
}
/**
* Return the dynamic field object information for a specified object
*/
async getDynamicFieldObject(input) {
return await this.transport.request({
method: "suix_getDynamicFieldObject",
params: [input.parentId, input.name],
signal: input.signal
});
}
/**
* Get the sequence number of the latest checkpoint that has been executed
*/
async getLatestCheckpointSequenceNumber({
signal
} = {}) {
const resp = await this.transport.request({
method: "sui_getLatestCheckpointSequenceNumber",
params: [],
signal
});
return String(resp);
}
/**
* Returns information about a given checkpoint
*/
async getCheckpoint(input) {
return await this.transport.request({
method: "sui_getCheckpoint",
params: [input.id],
signal: input.signal
});
}
/**
* Returns historical checkpoints paginated
*/
async getCheckpoints(input) {
return await this.transport.request({
method: "sui_getCheckpoints",
params: [input.cursor, input?.limit, input.descendingOrder],
signal: input.signal
});
}
/**
* Return the committee information for the asked epoch
*/
async getCommitteeInfo(input) {
return await this.transport.request({
method: "suix_getCommitteeInfo",
params: [input?.epoch],
signal: input?.signal
});
}
async getNetworkMetrics({ signal } = {}) {
return await this.transport.request({
method: "suix_getNetworkMetrics",
params: [],
signal
});
}
async getAddressMetrics({ signal } = {}) {
return await this.transport.request({
method: "suix_getLatestAddressMetrics",
params: [],
signal
});
}
async getEpochMetrics(input) {
return await this.transport.request({
method: "suix_getEpochMetrics",
params: [input?.cursor, input?.limit, input?.descendingOrder],
signal: input?.signal
});
}
async getAllEpochAddressMetrics(input) {
return await this.transport.request({
method: "suix_getAllEpochAddressMetrics",
params: [input?.descendingOrder],
signal: input?.signal
});
}
/**
* Return the committee information for the asked epoch
*/
async getEpochs(input) {
return await this.transport.request({
method: "suix_getEpochs",
params: [input?.cursor, input?.limit, input?.descendingOrder],
signal: input?.signal
});
}
/**
* Returns list of top move calls by usage
*/
async getMoveCallMetrics({ signal } = {}) {
return await this.transport.request({
method: "suix_getMoveCallMetrics",
params: [],
signal
});
}
/**
* Return the committee information for the asked epoch
*/
async getCurrentEpoch({ signal } = {}) {
return await this.transport.request({
method: "suix_getCurrentEpoch",
params: [],
signal
});
}
/**
* Return the Validators APYs
*/
async getValidatorsApy({ signal } = {}) {
return await this.transport.request({
method: "suix_getValidatorsApy",
params: [],
signal
});
}
// TODO: Migrate this to `sui_getChainIdentifier` once it is widely available.
async getChainIdentifier({ signal } = {}) {
const checkpoint = await this.getCheckpoint({ id: "0", signal });
const bytes = (0, import_bcs.fromBase58)(checkpoint.digest);
return (0, import_bcs.toHex)(bytes.slice(0, 4));
}
async resolveNameServiceAddress(input) {
return await this.transport.request({
method: "suix_resolveNameServiceAddress",
params: [input.name],
signal: input.signal
});
}
async resolveNameServiceNames({
format = "dot",
...input
}) {
const { nextCursor, hasNextPage, data } = await this.transport.request({
method: "suix_resolveNameServiceNames",
params: [input.address, input.cursor, input.limit],
signal: input.signal
});
return {
hasNextPage,
nextCursor,
data: data.map((name) => (0, import_suins.normalizeSuiNSName)(name, format))
};
}
async getProtocolConfig(input) {
return await this.transport.request({
method: "sui_getProtocolConfig",
params: [input?.version],
signal: input?.signal
});
}
async verifyZkLoginSignature(input) {
return await this.transport.request({
method: "sui_verifyZkLoginSignature",
params: [input.bytes, input.signature, input.intentScope, input.author],
signal: input.signal
});
}
/**
* Wait for a transaction block result to be available over the API.
* This can be used in conjunction with `executeTransactionBlock` to wait for the transaction to
* be available via the API.
* This currently polls the `getTransactionBlock` API to check for the transaction.
*/
async waitForTransaction({
signal,
timeout = 60 * 1e3,
pollInterval = 2 * 1e3,
...input
}) {
const timeoutSignal = AbortSignal.timeout(timeout);
const timeoutPromise = new Promise((_, reject) => {
timeoutSignal.addEventListener("abort", () => reject(timeoutSignal.reason));
});
timeoutPromise.catch(() => {
});
while (!timeoutSignal.aborted) {
signal?.throwIfAborted();
try {
return await this.getTransactionBlock(input);
} catch (e) {
await Promise.race([
new Promise((resolve) => setTimeout(resolve, pollInterval)),
timeoutPromise
]);
}
}
timeoutSignal.throwIfAborted();
throw new Error("Unexpected error while waiting for transaction block.");
}
experimental_asClientExtension() {
return {
name: "jsonRPC",
register: () => {
return this;
}
};
}
}
//# sourceMappingURL=client.js.map
;