UNPKG

@mysten/suins

Version:
256 lines (255 loc) 10.6 kB
"use strict"; 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