@mysten/suins
Version:
256 lines (255 loc) • 10.6 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 suins_client_exports = {};
__export(suins_client_exports, {
SuinsClient: () => SuinsClient
});
module.exports = __toCommonJS(suins_client_exports);
var import_utils = require("@mysten/sui/utils");
var import_constants = require("./constants.js");
var import_helpers = require("./helpers.js");
var import_pyth = require("./pyth/pyth.js");
class SuinsClient {
constructor(config) {
this.client = config.client;
this.network = config.network || "mainnet";
if (this.network === "mainnet") {
this.config = import_constants.mainPackage.mainnet;
} else if (this.network === "testnet") {
this.config = import_constants.mainPackage.testnet;
} else {
throw new Error("Invalid network");
}
}
/**
* Returns the price list for SuiNS names in the base asset.
*/
// Format:
// {
// [ 3, 3 ] => 500000000,
// [ 4, 4 ] => 100000000,
// [ 5, 63 ] => 20000000
// }
async getPriceList() {
if (!this.config.suins) throw new Error("Suins object ID is not set");
if (!this.config.packageId) throw new Error("Price list config not found");
const priceList = await this.client.getDynamicFieldObject({
parentId: this.config.suins,
name: {
type: (0, import_helpers.getConfigType)(
this.config.packageIdV1,
(0, import_helpers.getPricelistConfigType)(this.config.packageIdPricing)
),
value: { dummy_field: false }
}
});
if (!priceList?.data?.content || priceList.data.content.dataType !== "moveObject" || !("fields" in priceList.data.content)) {
throw new Error("Price list not found or content is invalid");
}
const fields = priceList.data.content.fields;
if (!fields.value || !fields.value.fields || !fields.value.fields.pricing) {
throw new Error("Pricing fields not found in the price list");
}
const contentArray = fields.value.fields.pricing.fields.contents;
const priceMap = /* @__PURE__ */ new Map();
for (const entry of contentArray) {
const keyFields = entry.fields.key.fields;
const key = [Number(keyFields.pos0), Number(keyFields.pos1)];
const value = Number(entry.fields.value);
priceMap.set(key, value);
}
return priceMap;
}
/**
* Returns the renewal price list for SuiNS names in the base asset.
*/
// Format:
// {
// [ 3, 3 ] => 500000000,
// [ 4, 4 ] => 100000000,
// [ 5, 63 ] => 20000000
// }
async getRenewalPriceList() {
if (!this.config.suins) throw new Error("Suins object ID is not set");
if (!this.config.packageId) throw new Error("Price list config not found");
const priceList = await this.client.getDynamicFieldObject({
parentId: this.config.suins,
name: {
type: (0, import_helpers.getConfigType)(
this.config.packageIdV1,
(0, import_helpers.getRenewalPricelistConfigType)(this.config.packageIdPricing)
),
value: { dummy_field: false }
}
});
if (!priceList || !priceList.data || !priceList.data.content || priceList.data.content.dataType !== "moveObject" || !("fields" in priceList.data.content)) {
throw new Error("Price list not found or content structure is invalid");
}
const fields = priceList.data.content.fields;
if (!fields.value || !fields.value.fields || !fields.value.fields.config || !fields.value.fields.config.fields.pricing || !fields.value.fields.config.fields.pricing.fields.contents) {
throw new Error("Pricing fields not found in the price list");
}
const contentArray = fields.value.fields.config.fields.pricing.fields.contents;
const priceMap = /* @__PURE__ */ new Map();
for (const entry of contentArray) {
const keyFields = entry.fields.key.fields;
const key = [Number(keyFields.pos0), Number(keyFields.pos1)];
const value = Number(entry.fields.value);
priceMap.set(key, value);
}
return priceMap;
}
/**
* Returns the coin discount list for SuiNS names.
*/
// Format:
// {
// 'b48aac3f53bab328e1eb4c5b3c34f55e760f2fb3f2305ee1a474878d80f650f0::TESTUSDC::TESTUSDC' => 0,
// '0000000000000000000000000000000000000000000000000000000000000002::sui::SUI' => 0,
// 'b48aac3f53bab328e1eb4c5b3c34f55e760f2fb3f2305ee1a474878d80f650f0::TESTNS::TESTNS' => 25
// }
async getCoinTypeDiscount() {
if (!this.config.suins) throw new Error("Suins object ID is not set");
if (!this.config.packageId) throw new Error("Price list config not found");
const dfValue = await this.client.getDynamicFieldObject({
parentId: this.config.suins,
name: {
type: (0, import_helpers.getConfigType)(
this.config.packageIdV1,
(0, import_helpers.getCoinDiscountConfigType)(this.config.payments.packageId)
),
value: { dummy_field: false }
}
});
if (!dfValue || !dfValue.data || !dfValue.data.content || dfValue.data.content.dataType !== "moveObject" || !("fields" in dfValue.data.content)) {
throw new Error("dfValue not found or content structure is invalid");
}
const fields = dfValue.data.content.fields;
if (!fields.value || !fields.value.fields || !fields.value.fields.base_currency || !fields.value.fields.base_currency.fields || !fields.value.fields.base_currency.fields.name || !fields.value.fields.currencies || !fields.value.fields.currencies.fields || !fields.value.fields.currencies.fields.contents) {
throw new Error("Required fields are missing in dfValue");
}
const content = fields.value.fields;
const currencyDiscounts = content.currencies.fields.contents;
const discountMap = /* @__PURE__ */ new Map();
for (const entry of currencyDiscounts) {
const key = entry.fields.key.fields.name;
const value = Number(entry.fields.value.fields.discount_percentage);
discountMap.set(key, value);
}
return discountMap;
}
async getNameRecord(name) {
if (!(0, import_utils.isValidSuiNSName)(name)) throw new Error("Invalid SuiNS name");
if (!this.config.registryTableId) throw new Error("Suins package ID is not set");
const nameRecord = await this.client.getDynamicFieldObject({
parentId: this.config.registryTableId,
name: {
type: (0, import_helpers.getDomainType)(this.config.packageIdV1),
value: (0, import_utils.normalizeSuiNSName)(name, "dot").split(".").reverse()
}
});
const fields = nameRecord.data?.content;
if (nameRecord.error?.code === "dynamicFieldNotFound") return null;
if (nameRecord.error || !fields || fields.dataType !== "moveObject")
throw new Error("Name record not found. This domain is not registered.");
const content = fields.fields;
const data = {};
content.value.fields.data.fields.contents.forEach((item) => {
data[item.fields.key] = item.fields.value;
});
return {
name,
nftId: content.value.fields?.nft_id,
targetAddress: content.value.fields?.target_address,
expirationTimestampMs: content.value.fields?.expiration_timestamp_ms,
data,
avatar: data.avatar,
contentHash: data.content_hash,
walrusSiteId: data.walrus_site_id
};
}
/**
* Calculates the registration or renewal price for an SLD (Second Level Domain).
* It expects a domain name, the number of years and a `SuinsPriceList` object,
* as returned from `suinsClient.getPriceList()` function, or `suins.getRenewalPriceList()` function.
*
* It throws an error:
* 1. if the name is a subdomain
* 2. if the name is not a valid SuiNS name
* 3. if the years are not between 1 and 5
*/
async calculatePrice({
name,
years,
isRegistration = true
}) {
if (!(0, import_utils.isValidSuiNSName)(name)) {
throw new Error("Invalid SuiNS name");
}
(0, import_helpers.validateYears)(years);
if ((0, import_helpers.isSubName)(name)) {
throw new Error("Subdomains do not have a registration fee");
}
const length = (0, import_utils.normalizeSuiNSName)(name, "dot").split(".")[0].length;
const priceList = await this.getPriceList();
const renewalPriceList = await this.getRenewalPriceList();
let yearsRemain = years;
let price = 0;
if (isRegistration) {
for (const [[minLength, maxLength], pricePerYear] of priceList.entries()) {
if (length >= minLength && length <= maxLength) {
price += pricePerYear;
yearsRemain -= 1;
break;
}
}
}
for (const [[minLength, maxLength], pricePerYear] of renewalPriceList.entries()) {
if (length >= minLength && length <= maxLength) {
price += yearsRemain * pricePerYear;
break;
}
}
return price;
}
async getPriceInfoObject(tx, feed) {
const endpoint = this.network === "testnet" ? "https://hermes-beta.pyth.network" : "https://hermes.pyth.network";
const connection = new import_pyth.SuiPriceServiceConnection(endpoint);
const priceIDs = [
feed
// ASSET/USD price ID
];
const priceUpdateData = await connection.getPriceFeedsUpdateData(priceIDs);
const wormholeStateId = this.config.pyth.wormholeStateId;
const pythStateId = this.config.pyth.pythStateId;
const client = new import_pyth.SuiPythClient(this.client, pythStateId, wormholeStateId);
return await client.updatePriceFeeds(tx, priceUpdateData, priceIDs);
}
async getObjectType(objectId) {
const objectResponse = await this.client.getObject({
id: objectId,
options: { showType: true }
});
if (objectResponse && objectResponse.data && objectResponse.data.type) {
return objectResponse.data.type;
}
throw new Error(`Type information not found for object ID: ${objectId}`);
}
}
//# sourceMappingURL=suins-client.js.map
;