@mysten/sui
Version:
Sui TypeScript API
139 lines (137 loc) • 5.14 kB
JavaScript
import { SUI_ADDRESS_LENGTH, normalizeStructTag, parseStructTag } from "../utils/sui-types.mjs";
import { TypeTagSerializer } from "../bcs/type-tag-serializer.mjs";
import { bcs as suiBcs } from "../bcs/index.mjs";
import { BaseClient } from "./client.mjs";
import { deriveDynamicFieldID } from "../utils/dynamic-fields.mjs";
import { MvrClient } from "./mvr.mjs";
//#region src/client/core.ts
const DEFAULT_MVR_URLS = {
mainnet: "https://mainnet.mvr.mystenlabs.com",
testnet: "https://testnet.mvr.mystenlabs.com"
};
var CoreClient = class extends BaseClient {
constructor(options) {
super(options);
this.core = this;
this.mvr = new MvrClient({
cache: this.cache.scope("core.mvr"),
url: options.mvr?.url ?? DEFAULT_MVR_URLS[this.network],
pageSize: options.mvr?.pageSize,
overrides: options.mvr?.overrides
});
}
async getObject(options) {
const { objectId } = options;
const { objects: [result] } = await this.getObjects({
objectIds: [objectId],
signal: options.signal,
include: options.include
});
if (result instanceof Error) throw result;
return { object: result };
}
async getDynamicField(options) {
const normalizedNameType = TypeTagSerializer.parseFromStr((await this.core.mvr.resolveType({ type: options.name.type })).type);
const fieldId = deriveDynamicFieldID(options.parentId, normalizedNameType, options.name.bcs);
const { objects: [fieldObject] } = await this.getObjects({
objectIds: [fieldId],
signal: options.signal,
include: {
previousTransaction: true,
content: true
}
});
if (fieldObject instanceof Error) throw fieldObject;
const fieldType = parseStructTag(fieldObject.type);
const content = await fieldObject.content;
const nameTypeParam = fieldType.typeParams[0];
const isDynamicObject = typeof nameTypeParam !== "string" && nameTypeParam.module === "dynamic_object_field" && nameTypeParam.name === "Wrapper";
const valueBcs = content.slice(SUI_ADDRESS_LENGTH + options.name.bcs.length);
const valueType = typeof fieldType.typeParams[1] === "string" ? fieldType.typeParams[1] : normalizeStructTag(fieldType.typeParams[1]);
return { dynamicField: {
$kind: isDynamicObject ? "DynamicObject" : "DynamicField",
fieldId: fieldObject.objectId,
digest: fieldObject.digest,
version: fieldObject.version,
type: fieldObject.type,
previousTransaction: fieldObject.previousTransaction,
name: {
type: typeof nameTypeParam === "string" ? nameTypeParam : normalizeStructTag(nameTypeParam),
bcs: options.name.bcs
},
value: {
type: valueType,
bcs: valueBcs
},
childId: isDynamicObject ? suiBcs.Address.parse(valueBcs) : void 0
} };
}
async getDynamicObjectField(options) {
const wrappedType = `0x2::dynamic_object_field::Wrapper<${(await this.core.mvr.resolveType({ type: options.name.type })).type}>`;
const { dynamicField } = await this.getDynamicField({
parentId: options.parentId,
name: {
type: wrappedType,
bcs: options.name.bcs
},
signal: options.signal
});
const { object } = await this.getObject({
objectId: dynamicField.childId,
signal: options.signal,
include: options.include
});
return { object };
}
async waitForTransaction(options) {
const { signal, timeout = 60 * 1e3, pollSchedule, include } = options;
const digest = "result" in options && options.result ? (options.result.Transaction ?? options.result.FailedTransaction).digest : options.digest;
const abortSignal = signal ? AbortSignal.any([AbortSignal.timeout(timeout), signal]) : AbortSignal.timeout(timeout);
const abortPromise = new Promise((_, reject) => {
abortSignal.addEventListener("abort", () => reject(abortSignal.reason));
});
abortPromise.catch(() => {});
const schedule = pollSchedule ?? [
0,
300,
600,
1500,
3500
];
const t0 = Date.now();
let scheduleIndex = 0;
const lastInterval = schedule.length > 0 ? schedule[schedule.length - 1] - (schedule[schedule.length - 2] ?? 0) : 2e3;
while (true) {
if (scheduleIndex < schedule.length) {
const remaining = t0 + schedule[scheduleIndex] - Date.now();
scheduleIndex++;
if (remaining > 0) await Promise.race([new Promise((resolve) => setTimeout(resolve, remaining)), abortPromise]);
} else await Promise.race([new Promise((resolve) => setTimeout(resolve, lastInterval)), abortPromise]);
abortSignal.throwIfAborted();
try {
return await this.getTransaction({
digest,
include,
signal: abortSignal
});
} catch {}
}
}
async signAndExecuteTransaction({ transaction, signer, additionalSignatures = [], ...input }) {
let transactionBytes;
if (transaction instanceof Uint8Array) transactionBytes = transaction;
else {
transaction.setSenderIfNotSet(signer.toSuiAddress());
transactionBytes = await transaction.build({ client: this });
}
const { signature } = await signer.signTransaction(transactionBytes);
return this.executeTransaction({
transaction: transactionBytes,
signatures: [signature, ...additionalSignatures],
...input
});
}
};
//#endregion
export { CoreClient };
//# sourceMappingURL=core.mjs.map