aftermath-ts-sdk
Version:
Aftermath TypeScript SDK
757 lines (756 loc) • 43.3 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SuiFrensApi = void 0;
const transactions_1 = require("@mysten/sui/transactions");
const bcs_1 = require("@mysten/sui/bcs");
const coin_1 = require("../../coin/coin");
const helpers_1 = require("../../../general/utils/helpers");
const utils_1 = require("../../../general/utils");
const eventsApiHelpers_1 = require("../../../general/apiHelpers/eventsApiHelpers");
const sui_1 = require("../../sui/sui");
const suiFrens_1 = require("../suiFrens");
class SuiFrensApi {
// =========================================================================
// Constructor
// =========================================================================
constructor(Provider) {
this.Provider = Provider;
// =========================================================================
// Public Methods
// =========================================================================
// =========================================================================
// Inspections
// =========================================================================
this.fetchMixingLimitsAndLastEpochMixeds = (inputs) => __awaiter(this, void 0, void 0, function* () {
const tx = new transactions_1.Transaction();
this.devInspectMixLimitAndLastEpochMixedMulTx(Object.assign(Object.assign({}, inputs), { tx }));
const [mixLimitBytes, lastEpochMixedBytes] = yield this.Provider.Inspections().fetchAllBytesFromTxOutput({
tx,
});
const mixLimits = bcs_1.bcs
.vector(bcs_1.bcs.option(bcs_1.bcs.u8()))
.parse(new Uint8Array(mixLimitBytes));
const lastEpochMixeds = bcs_1.bcs
.vector(bcs_1.bcs.option(bcs_1.bcs.u64()))
.parse(new Uint8Array(lastEpochMixedBytes));
return mixLimits.map((mixLimit, index) => ({
mixLimit: mixLimit === null || mixLimit === undefined
? undefined
: BigInt(mixLimit),
lastEpochMixed: lastEpochMixeds[index] === undefined
? undefined
: BigInt(lastEpochMixeds[index]),
}));
});
this.fetchMixingLimit = (inputs) => __awaiter(this, void 0, void 0, function* () {
// TODO: handle bullshark types more cleanly
if (inputs.suiFrenType === this.objectTypes.bullshark)
return undefined;
const tx = new transactions_1.Transaction();
this.mixingLimitTx(Object.assign({ tx }, inputs));
const bytes = yield this.Provider.Inspections().fetchFirstBytesFromTxOutput({
tx,
});
const unwrapped = bcs_1.bcs.option(bcs_1.bcs.u8()).parse(new Uint8Array(bytes));
return unwrapped === null || unwrapped === undefined
? undefined
: BigInt(unwrapped);
});
this.fetchLastEpochMixed = (inputs) => __awaiter(this, void 0, void 0, function* () {
// TODO: handle bullshark types more cleanly
if (inputs.suiFrenType === this.objectTypes.bullshark)
return undefined;
const tx = new transactions_1.Transaction();
this.lastEpochMixedTx(Object.assign({ tx }, inputs));
const bytes = yield this.Provider.Inspections().fetchFirstBytesFromTxOutput({
tx,
});
const unwrapped = bcs_1.bcs.option(bcs_1.bcs.u64()).parse(new Uint8Array(bytes));
return unwrapped === null || unwrapped === undefined
? undefined
: BigInt(unwrapped);
});
this.fetchStakedSuiFrenMetadataIds = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { suiFrenIds } = inputs;
const tx = new transactions_1.Transaction();
this.devInspectMetadataObjectIdMulTx({ tx, suiFrenIds });
const idBytes = yield this.Provider.Inspections().fetchFirstBytesFromTxOutput({
tx,
});
const stakedSuiFrenMetadataIds = bcs_1.bcs
.vector(bcs_1.bcs.Address)
.parse(new Uint8Array(idBytes));
return stakedSuiFrenMetadataIds;
});
// =========================================================================
// Events
// =========================================================================
this.fetchHarvestSuiFrenFeesEvents = (inputs) => this.Provider.Events().fetchCastEventsWithCursor(Object.assign(Object.assign({}, inputs), { query: {
MoveEventType: this.eventTypes.harvestSuiFrenFees,
}, eventFromEventOnChain: utils_1.Casting.suiFrens.harvestSuiFrenFeesEventFromOnChain }));
this.fetchMixSuiFrensEvents = (inputs) => this.Provider.Events().fetchCastEventsWithCursor(Object.assign(Object.assign({}, inputs), { query: {
MoveEventType: this.eventTypes.mixSuiFrens,
}, eventFromEventOnChain: utils_1.Casting.suiFrens.mixSuiFrensEventFromOnChain }));
this.fetchStakeSuiFrenEvents = (inputs) => this.Provider.Events().fetchCastEventsWithCursor(Object.assign(Object.assign({}, inputs), { query: {
MoveEventType: this.eventTypes.stakeSuiFren,
}, eventFromEventOnChain: utils_1.Casting.suiFrens.stakeSuiFrenEventFromOnChain }));
this.fetchUnstakeSuiFrenEvents = (inputs) => this.Provider.Events().fetchCastEventsWithCursor(Object.assign(Object.assign({}, inputs), { query: {
MoveEventType: this.eventTypes.unstakeSuiFren,
}, eventFromEventOnChain: utils_1.Casting.suiFrens.unstakeSuiFrenEventFromOnChain }));
// =========================================================================
// Objects
// =========================================================================
// =========================================================================
// CapyLabsApp Object
// =========================================================================
this.fetchCapyLabsApp = () => __awaiter(this, void 0, void 0, function* () {
return this.Provider.Objects().fetchCastObject({
objectId: this.addresses.objects.capyLabsApp,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens.capyLabsAppObjectFromSuiObjectResponse,
});
});
this.fetchSuiFrenVaultStateV1Object = () => __awaiter(this, void 0, void 0, function* () {
return this.Provider.Objects().fetchCastObject({
objectId: this.addresses.objects.suiFrensVaultStateV1,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens.suiFrenVaultStateV1ObjectFromSuiObjectResponse,
});
});
// =========================================================================
// SuiFren Objects
// =========================================================================
this.fetchSuiFrens = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { suiFrenIds } = inputs;
const partialSuiFrens = yield this.Provider.Objects().fetchCastObjectBatch({
objectIds: suiFrenIds,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens.partialSuiFrenObjectFromSuiObjectResponse,
options: {
showDisplay: true,
showType: true,
showContent: true,
},
});
return this.fetchCompletePartialSuiFrenObjects({
partialSuiFrens,
isStaked: false,
});
});
this.fetchOwnedSuiFrens = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { walletAddress } = inputs;
const [partialSuiFrenNonBullsharks, partialSuiFrenBullsharks] = yield Promise.all([
this.Provider.Objects().fetchCastObjectsOwnedByAddressOfType({
walletAddress,
objectType: this.objectTypes.suiFren,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens
.partialSuiFrenObjectFromSuiObjectResponse,
withDisplay: true,
}),
this.fetchOwnedPartialSuiFrenBullsharks(inputs),
]);
const suiFrens = yield this.fetchCompletePartialSuiFrenObjects({
partialSuiFrens: [
...partialSuiFrenNonBullsharks,
...partialSuiFrenBullsharks,
],
isStaked: false,
});
return suiFrens;
});
this.fetchStakedSuiFrens = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { stakedSuiFrenIds } = inputs;
const stakedSuiFrenData = yield this.Provider.Objects().fetchCastObjectBatch({
objectIds: stakedSuiFrenIds,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens
.partialSuiFrenAndStakedSuiFrenMetadataV1ObjectFromSuiObjectResponse,
options: {
showDisplay: true,
showType: true,
showContent: true,
},
});
const suiFrens = yield this.fetchCompletePartialSuiFrenObjects({
partialSuiFrens: stakedSuiFrenData.map((data) => data.partialSuiFren),
isStaked: true,
});
return suiFrens.map((suiFren, index) => ({
suiFren,
metadata: stakedSuiFrenData[index].stakedSuiFrenMetadata,
}));
});
this.fetchStakedSuiFrensDynamicFields = (inputs) => {
return this.Provider.DynamicFields().fetchCastDynamicFieldsOfTypeWithCursor(Object.assign(Object.assign({}, inputs), { parentObjectId: this.addresses.objects.suiFrensVaultStateV1MetadataTable, objectsFromObjectIds: (stakedSuiFrenIds) => this.fetchStakedSuiFrens({ stakedSuiFrenIds }), dynamicFieldType: this.objectTypes.stakedSuiFrenMetadataV1 }));
};
// =========================================================================
// Accessories
// =========================================================================
this.fetchAccessoriesForSuiFren = (inputs) => __awaiter(this, void 0, void 0, function* () {
return yield this.Provider.DynamicFields().fetchCastAllDynamicFieldsOfType({
parentObjectId: inputs.suiFrenId,
objectsFromObjectIds: (objectIds) => this.fetchAccessories({ objectIds }),
dynamicFieldType: this.objectTypes.suiFrenAccessory,
});
});
this.fetchOwnedAccessories = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { walletAddress } = inputs;
return yield this.Provider.Objects().fetchCastObjectsOwnedByAddressOfType({
walletAddress,
objectType: this.objectTypes.suiFrenAccessory,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens.accessoryObjectFromSuiObjectResponse,
withDisplay: true,
});
});
this.fetchAccessories = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { objectIds } = inputs;
return this.Provider.Objects().fetchCastObjectBatch({
objectIds,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens.accessoryObjectFromSuiObjectResponse,
options: {
showDisplay: true,
showType: true,
showContent: true,
},
});
});
// =========================================================================
// Staked SuiFren Objects
// =========================================================================
// TODO: handle sorting
this.fetchStakedSuiFrensDynamicFieldsWithFilters = (inputs) => __awaiter(this, void 0, void 0, function* () {
var _a;
const { attributes } = inputs;
const defaultLimit = 25;
const limit = (_a = inputs.limit) !== null && _a !== void 0 ? _a : defaultLimit;
const isComplete = (data) => {
return (this.filterSuiFrensWithAttributes({
suiFrens: data.map((info) => info.suiFren),
attributes,
}).length >= limit);
};
const suiFrensWithCursor = yield this.Provider.DynamicFields().fetchDynamicFieldsUntil(Object.assign(Object.assign({}, inputs), { fetchFunc: (data) => this.fetchStakedSuiFrensDynamicFields(data), isComplete }));
const filteredSuiFrens = this.filterSuiFrensWithAttributes({
suiFrens: suiFrensWithCursor.dynamicFieldObjects.map((data) => data.suiFren),
attributes,
});
const dynamicFieldObjects = suiFrensWithCursor.dynamicFieldObjects.filter((data) => filteredSuiFrens
.slice(0, limit)
.some((suiFren) => suiFren.objectId === data.suiFren.objectId));
const resizedSuiFrensWithCursor = {
nextCursor: limit < filteredSuiFrens.length
? filteredSuiFrens[limit].objectId
: suiFrensWithCursor.nextCursor,
dynamicFieldObjects,
};
return resizedSuiFrensWithCursor;
});
this.fetchOwnedStakedSuiFrens = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { walletAddress } = inputs;
const stakedPositions = yield this.Provider.Objects().fetchCastObjectsOwnedByAddressOfType({
walletAddress,
objectType: this.objectTypes.stakedSuiFrenPosition,
objectFromSuiObjectResponse: utils_1.Casting.suiFrens.stakedSuiFrenPositionFromSuiObjectResponse,
});
const stakedSuiFrenIds = yield this.fetchStakedSuiFrenMetadataIds({
suiFrenIds: stakedPositions.map((position) => position.suiFrenId),
});
const stakedSuiFrens = yield this.fetchStakedSuiFrens({
stakedSuiFrenIds,
});
return stakedSuiFrens.map((data, index) => (Object.assign(Object.assign({}, data), { position: stakedPositions[index] })));
});
// =========================================================================
// Transaction Commands
// =========================================================================
// =========================================================================
// Inspections
// =========================================================================
this.devInspectMetadataObjectIdMulTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "dev_inspect_metadata_object_id_mul"),
typeArguments: [],
arguments: [
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.pure(bcs_1.bcs.vector(bcs_1.bcs.Address).serialize(inputs.suiFrenIds)), // suifren_ids
],
});
};
this.devInspectMixLimitAndLastEpochMixedMulTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVaultCapyLabsExtension, SuiFrensApi.constants.moduleNames.suiFrensVaultCapyLabsExtension
.capyLabs, "dev_inspect_mixing_limit_and_last_epoch_mixed_mul"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVaultCapyLabsExtension), // SuiFrensVaultCapyLabsExt
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.pure(bcs_1.bcs.vector(bcs_1.bcs.Address).serialize(inputs.suiFrenIds)), // suifren_ids
],
});
};
this.mixingLimitTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrens, SuiFrensApi.constants.moduleNames.capyLabs.capyLabs, "mixing_limit"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(inputs.suiFrenId), // SuiFren
],
});
};
this.lastEpochMixedTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrens, SuiFrensApi.constants.moduleNames.capyLabs.capyLabs, "last_epoch_mixed"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(inputs.suiFrenId), // SuiFren
],
});
};
// =========================================================================
// Mixing Transaction Commands
// =========================================================================
this.mixAndKeepTx = (inputs) => {
const { tx, suiPaymentCoinId } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVaultCapyLabsExtension, SuiFrensApi.constants.moduleNames.suiFrensVaultCapyLabsExtension
.capyLabs, "mix_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVaultCapyLabsExtension), // SuiFrensVaultCapyLabsExt
tx.object(this.addresses.objects.capyLabsApp), // CapyLabsApp
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.parentOneId), // SuiFren
tx.object(inputs.parentTwoId), // SuiFren
typeof suiPaymentCoinId === "string"
? tx.object(suiPaymentCoinId)
: suiPaymentCoinId, // Coin
tx.object(sui_1.Sui.constants.addresses.suiClockId), // Clock
],
});
};
this.mixWithStakedAndKeepTx = (inputs) => {
const { tx, suiPaymentCoinId } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVaultCapyLabsExtension, SuiFrensApi.constants.moduleNames.suiFrensVaultCapyLabsExtension
.capyLabs, "mix_with_staked_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVaultCapyLabsExtension), // SuiFrensVaultCapyLabsExt
tx.object(this.addresses.objects.capyLabsApp), // CapyLabsApp
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.nonStakedParentId), // SuiFren
tx.object(inputs.stakedParentId), // SuiFren
typeof suiPaymentCoinId === "string"
? tx.object(suiPaymentCoinId)
: suiPaymentCoinId, // Coin
tx.object(sui_1.Sui.constants.addresses.suiClockId), // Clock
],
});
};
this.mixStakedWithStakedAndKeepTx = (inputs) => {
const { tx, suiPaymentCoinId } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVaultCapyLabsExtension, SuiFrensApi.constants.moduleNames.suiFrensVaultCapyLabsExtension
.capyLabs, "mix_staked_with_staked_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVaultCapyLabsExtension), // SuiFrensVaultCapyLabsExt
tx.object(this.addresses.objects.capyLabsApp), // CapyLabsApp
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.parentOneId), // SuiFren
tx.object(inputs.parentTwoId), // SuiFren
typeof suiPaymentCoinId === "string"
? tx.object(suiPaymentCoinId)
: suiPaymentCoinId, // Coin
tx.object(sui_1.Sui.constants.addresses.suiClockId), // Clock
],
});
};
// =========================================================================
// Staking Transaction Commands
// =========================================================================
this.stakeAndKeepTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVaultCapyLabsExtension, SuiFrensApi.constants.moduleNames.suiFrensVaultCapyLabsExtension
.capyLabs, "stake_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVaultCapyLabsExtension), // SuiFrensVaultCapyLabsExt
tx.object(this.addresses.objects.capyLabsApp), // CapyLabsApp
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.suiFrenId), // SuiFren
tx.pure.bool(inputs.autoStakeFees),
tx.pure.u64(inputs.baseFee),
tx.pure.u64(inputs.feeIncrementPerMix),
tx.pure.u8(Number(inputs.minRemainingMixesToKeep)),
],
});
};
this.unstakeAndKeepTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVaultCapyLabsExtension, SuiFrensApi.constants.moduleNames.suiFrensVaultCapyLabsExtension
.capyLabs, "unstake_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVaultCapyLabsExtension), // SuiFrensVaultCapyLabsExt
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.stakedPositionId), // StakedPosition
],
});
};
// =========================================================================
// Fee Harvest Transaction Commands
// =========================================================================
this.beginHarvestTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "begin_harvest"),
typeArguments: [],
arguments: [],
});
};
this.harvestTx = (inputs) => {
const { tx, harvestFeesEventMetadataId } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "harvest"),
typeArguments: [],
arguments: [
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.stakedPositionId), // StakedPosition
typeof harvestFeesEventMetadataId === "string"
? tx.object(harvestFeesEventMetadataId)
: harvestFeesEventMetadataId, // HarvestedFeesEventMetadata
],
});
};
this.endHarvestTx = (inputs) => {
const { tx, harvestFeesEventMetadataId } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "end_harvest"),
typeArguments: [],
arguments: [
typeof harvestFeesEventMetadataId === "string"
? tx.object(harvestFeesEventMetadataId)
: harvestFeesEventMetadataId, // HarvestedFeesEventMetadata
],
});
};
// =========================================================================
// Accessory Transaction Commands
// =========================================================================
this.addAccessoryTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "add_accessory"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.suiFrenId), // suifren_id
tx.object(inputs.accessoryId), // Accessory
],
});
};
this.addAccessoryToOwnedSuiFrenTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "add_accessory_to_owned_suifren"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(inputs.suiFrenId), // suifren_id
tx.object(inputs.accessoryId), // Accessory
],
});
};
this.removeAccessoryAndKeepTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "remove_accessory_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(this.addresses.objects.suiFrensVault), // SuiFrenVault
tx.object(inputs.stakedPositionId), // StakedPosition
tx.object(inputs.accessoryType), // String
],
});
};
this.removeAccessoryFromOwnedSuiFrenAndKeepTx = (inputs) => {
const { tx } = inputs;
return tx.moveCall({
target: helpers_1.Helpers.transactions.createTxTarget(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.vault, "remove_accessory_from_owned_suifren_and_keep"),
typeArguments: [inputs.suiFrenType],
arguments: [
tx.object(inputs.suiFrenId), // SuiFren
tx.object(inputs.accessoryType), // String
],
});
};
// =========================================================================
// Transactions
// =========================================================================
// =========================================================================
// Staking Transactions
// =========================================================================
this.fetchStakeTx = helpers_1.Helpers.transactions.createBuildTxFunc((inputs) => this.stakeAndKeepTx(Object.assign(Object.assign({}, inputs), { autoStakeFees: true })));
this.fetchUnstakeTx = helpers_1.Helpers.transactions.createBuildTxFunc(this.unstakeAndKeepTx);
// =========================================================================
// Mixing Transactions
// =========================================================================
this.fetchBuildMixTx = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { walletAddress, suiFrenParentOne, suiFrenParentTwo, suiFrenType, baseFee, isSponsoredTx, } = inputs;
const tx = new transactions_1.Transaction();
tx.setSender(walletAddress);
const totalFee = baseFee +
suiFrens_1.SuiFrens.calcTotalInternalMixFee({
mixFee1: suiFrenParentOne.mixFee,
mixFee2: suiFrenParentTwo.mixFee,
});
const suiPaymentCoinId = yield this.Provider.Coin().fetchCoinWithAmountTx({
tx,
walletAddress,
coinType: coin_1.Coin.constants.suiCoinType,
coinAmount: totalFee,
isSponsoredTx,
});
const isParentOneStaked = suiFrenParentOne.mixFee !== undefined;
const isParentTwoStaked = suiFrenParentTwo.mixFee !== undefined;
const parentOneId = suiFrenParentOne.objectId;
const parentTwoId = suiFrenParentTwo.objectId;
if (isParentOneStaked && isParentTwoStaked) {
// both staked
this.mixStakedWithStakedAndKeepTx({
tx,
parentOneId,
parentTwoId,
suiPaymentCoinId,
suiFrenType,
});
}
else if (!isParentOneStaked && !isParentTwoStaked) {
// neither staked
this.mixAndKeepTx({
tx,
parentOneId,
parentTwoId,
suiPaymentCoinId,
suiFrenType,
});
}
else {
// only one staked
const [nonStakedParentId, stakedParentId] = isParentOneStaked
? [parentTwoId, parentOneId]
: [parentOneId, parentTwoId];
this.mixWithStakedAndKeepTx({
tx,
nonStakedParentId,
stakedParentId,
suiPaymentCoinId,
suiFrenType,
});
}
return tx;
});
// =========================================================================
// Fee Harvesting Transactions
// =========================================================================
this.fetchBuildHarvestFeesTx = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { stakedPositionIds } = inputs;
const tx = new transactions_1.Transaction();
tx.setSender(inputs.walletAddress);
const harvestFeesEventMetadataId = this.beginHarvestTx({ tx });
let harvestedCoins = [];
for (const stakedPositionId of stakedPositionIds) {
const harvestedCoin = this.harvestTx({
tx,
stakedPositionId,
harvestFeesEventMetadataId,
});
harvestedCoins.push(harvestedCoin);
}
// TODO: move this merging & transferring behaviour to coins api helpers ?
const coinToTransfer = harvestedCoins[0];
if (harvestedCoins.length > 1)
tx.mergeCoins(coinToTransfer, harvestedCoins.slice(1));
tx.transferObjects([coinToTransfer], inputs.walletAddress);
this.endHarvestTx({ tx, harvestFeesEventMetadataId });
return tx;
});
// =========================================================================
// Accessory Transactions
// =========================================================================
this.fetchBuildAddAccessoryTx = (inputs) => {
if (inputs.isOwned) {
return helpers_1.Helpers.transactions.createBuildTxFunc(this.addAccessoryToOwnedSuiFrenTx)(inputs);
}
return helpers_1.Helpers.transactions.createBuildTxFunc(this.addAccessoryTx)(inputs);
};
this.fetchBuildRemoveAccessoryTx = (inputs) => {
if ("suiFrenId" in inputs) {
return helpers_1.Helpers.transactions.createBuildTxFunc(this.removeAccessoryFromOwnedSuiFrenAndKeepTx)(inputs);
}
return helpers_1.Helpers.transactions.createBuildTxFunc(this.removeAccessoryAndKeepTx)(inputs);
};
// =========================================================================
// Stats
// =========================================================================
this.fetchSuiFrenStats = () => __awaiter(this, void 0, void 0, function* () {
const [suiFrenVault, mixSuiFrenEventsWithinTime] = yield Promise.all([
this.fetchSuiFrenVaultStateV1Object(),
this.Provider.Events().fetchEventsWithinTime({
fetchEventsFunc: this.fetchMixSuiFrensEvents,
timeUnit: "hour",
time: 24,
}),
]);
const mixingFees24hr = helpers_1.Helpers.sumBigInt(mixSuiFrenEventsWithinTime.map((event) => event.fee));
return {
totalMixes: suiFrenVault.totalMixes,
currentTotalStaked: suiFrenVault.stakedSuiFrens,
mixingVolume24hr: mixSuiFrenEventsWithinTime.length,
mixingFees24hr,
};
});
// =========================================================================
// SuiFren Attribute Filtering
// =========================================================================
this.filterSuiFrensWithAttributes = (inputs) => {
const { suiFrens, attributes } = inputs;
if (Object.keys(attributes).length <= 0)
return suiFrens;
return suiFrens.filter((suiFren) => Object.entries(attributes).every(([key1, val1]) => Object.entries(suiFren.attributes).some(([key2, val2]) => key1.toLowerCase() === key2.toLowerCase() &&
val1.toLowerCase() === val2.toLowerCase())));
};
// =========================================================================
// Helpers
// =========================================================================
// TODO: remove or update
// public isSuiFrenObjectType = (suiObjectInfo: SuiObjectInfo): boolean =>
// suiObjectInfo.type === this.objectTypes.suiFren;
// =========================================================================
// Private Methods
// =========================================================================
// =========================================================================
// Helpers
// =========================================================================
this.fetchCompletePartialSuiFrenObjects = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { partialSuiFrens, isStaked } = inputs;
if (!isStaked) {
return Promise.all(partialSuiFrens.map((partialSuiFren) => this.fetchNonStakedCompletePartialSuiFrenObject({
partialSuiFren,
})));
}
if (partialSuiFrens.length <= 0)
return [];
const [partialSuiFrenBullsharks, partialSuiFrenNonBullsharks] = helpers_1.Helpers.bifilter(partialSuiFrens, (partialSuiFren) => partialSuiFren.objectType.includes(this.objectTypes.bullshark));
// TODO: handle different suifren types
const bullsharkDynamicFields = partialSuiFrenBullsharks.map(() => ({
mixLimit: undefined,
lastEpochMixed: undefined,
}));
const nonBullsharkDynamicFields = yield this.fetchMixingLimitsAndLastEpochMixeds({
suiFrenIds: partialSuiFrenNonBullsharks.map((suiFren) => suiFren.objectId),
suiFrenType: coin_1.Coin.getInnerCoinType(partialSuiFrenNonBullsharks[0].objectType),
});
const suiFrenBullsharks = bullsharkDynamicFields.map((data, index) => (Object.assign(Object.assign({}, partialSuiFrenBullsharks[index]), data)));
const suiFrenNonBullsharks = nonBullsharkDynamicFields.map((data, index) => (Object.assign(Object.assign({}, partialSuiFrenNonBullsharks[index]), data)));
return [...suiFrenBullsharks, ...suiFrenNonBullsharks];
});
this.fetchNonStakedCompletePartialSuiFrenObject = (inputs) => __awaiter(this, void 0, void 0, function* () {
const { partialSuiFren } = inputs;
const suiFrenId = partialSuiFren.objectId;
// TODO: move inner coin type func to general func in helpers
const suiFrenType = coin_1.Coin.getInnerCoinType(partialSuiFren.objectType);
const [mixLimit, lastEpochMixed] = yield Promise.all([
this.fetchMixingLimit({ suiFrenId, suiFrenType }),
this.fetchLastEpochMixed({ suiFrenId, suiFrenType }),
]);
return Object.assign(Object.assign({}, partialSuiFren), { mixLimit,
lastEpochMixed });
});
// TODO: refactor to use NftsApi class
this.fetchOwnedPartialSuiFrenBullsharks = (inputs) => __awaiter(this, void 0, void 0, function* () {
const kioskOwnerCaps = yield this.Provider.Nfts().fetchOwnedKioskOwnerCaps(inputs);
const allBullsharks = yield Promise.all(kioskOwnerCaps.map((kioskOwnerCap) => this.Provider.DynamicFields().fetchCastAllDynamicFieldsOfType({
parentObjectId: kioskOwnerCap.kioskObjectId,
objectsFromObjectIds: (suiFrenIds) => this.fetchSuiFrens({ suiFrenIds }),
dynamicFieldType: (fieldType) => fieldType.includes(this.objectTypes.suiFren) &&
fieldType.includes(this.objectTypes.bullshark),
})));
const bullsharks = allBullsharks.reduce((acc, bullsharks) => [...acc, ...bullsharks], []);
return bullsharks;
});
// =========================================================================
// Event Types
// =========================================================================
this.harvestSuiFrenFeesEventType = () => eventsApiHelpers_1.EventsApiHelpers.createEventType(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.events, SuiFrensApi.constants.eventNames.suiFrensVault.harvestSuiFrenFees);
this.mixSuiFrensEventType = () => eventsApiHelpers_1.EventsApiHelpers.createEventType(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.events, SuiFrensApi.constants.eventNames.suiFrensVault.mixSuiFrens);
this.stakeSuiFrenEventType = () => eventsApiHelpers_1.EventsApiHelpers.createEventType(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.events, SuiFrensApi.constants.eventNames.suiFrensVault.stakeSuiFren);
this.unstakeSuiFrenEventType = () => eventsApiHelpers_1.EventsApiHelpers.createEventType(this.addresses.packages.suiFrensVault, SuiFrensApi.constants.moduleNames.suiFrensVault.events, SuiFrensApi.constants.eventNames.suiFrensVault.unstakeSuiFren);
const addresses = this.Provider.addresses.suiFrens;
if (!addresses)
throw new Error("not all required addresses have been set in provider");
this.addresses = addresses;
this.objectTypes = {
// suiFrens
suiFren: `${addresses.packages.suiFrens}::${SuiFrensApi.constants.moduleNames.suiFrens.suiFrens}::SuiFren`,
capy: `${addresses.packages.suiFrens}::capy::Capy`,
bullshark: `${addresses.packages.suiFrensBullshark}::bullshark::Bullshark`,
// accessories
suiFrenAccessory: `${addresses.packages.accessories}::${SuiFrensApi.constants.moduleNames.accessories.accessories}::Accessory`,
// staking
stakedSuiFrenPosition: `${addresses.packages.suiFrensVault}::${SuiFrensApi.constants.moduleNames.suiFrensVault.stakedPosition}::StakedPosition`,
stakedSuiFrenMetadataV1: `${addresses.packages.suiFrensVault}::${SuiFrensApi.constants.moduleNames.suiFrensVault.vaultState}::StakedSuiFrenMetadataV1`,
};
this.eventTypes = {
harvestSuiFrenFees: this.harvestSuiFrenFeesEventType(),
mixSuiFrens: this.mixSuiFrensEventType(),
stakeSuiFren: this.stakeSuiFrenEventType(),
unstakeSuiFren: this.unstakeSuiFrenEventType(),
};
}
}
exports.SuiFrensApi = SuiFrensApi;
// =========================================================================
// Constants
// =========================================================================
SuiFrensApi.constants = {
moduleNames: {
suiFrens: {
suiFrens: "suifrens",
},
accessories: {
accessories: "accessories",
},
capyLabs: {
capyLabs: "capy_labs",
},
suiFrensVault: {
vault: "vault",
vaultState: "vault_state",
events: "events",
stakedPosition: "staked_position",
},
suiFrensVaultCapyLabsExtension: {
capyLabs: "capy_labs",
},
},
eventNames: {
suiFrensVault: {
mixSuiFrens: "MixedSuiFrenEvent",
stakeSuiFren: "StakedSuiFrenEvent",
unstakeSuiFren: "UnstakedSuiFrenEvent",
harvestSuiFrenFees: "HarvestedFeesEvent",
},
},
};