@hashgraphonline/standards-sdk
Version:
The Hashgraph Online Standards SDK provides a complete implementation of the Hashgraph Consensus Standards (HCS), giving developers all the tools needed to build applications on Hedera.
159 lines (158 loc) • 6.31 kB
JavaScript
import { CustomFeeType } from "./standards-sdk.es31.js";
import { HederaMirrorNode } from "./standards-sdk.es29.js";
class FeeConfigBuilder {
constructor(options) {
this.customFees = [];
this.logger = options.logger;
this.mirrorNode = new HederaMirrorNode(options.network, options.logger);
this.defaultCollectorAccountId = options.defaultCollectorAccountId || "";
}
/**
* Static factory method to create a FeeConfigBuilder with a single HBAR fee.
* @param hbarAmount Amount in HBAR.
* @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.
* @param network Network type ('mainnet' or 'testnet').
* @param logger Logger instance.
* @param exemptAccounts Optional array of account IDs exempt from this fee.
* @returns A configured FeeConfigBuilder instance.
*/
static forHbar(hbarAmount, collectorAccountId, network, logger, exemptAccounts = []) {
const builder = new FeeConfigBuilder({
network,
logger,
defaultCollectorAccountId: collectorAccountId
});
return builder.addHbarFee(hbarAmount, collectorAccountId, exemptAccounts);
}
/**
* Static factory method to create a FeeConfigBuilder with a single token fee.
* Automatically fetches token decimals if not provided.
* @param tokenAmount Amount of tokens.
* @param feeTokenId Token ID for the fee.
* @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.
* @param network Network type ('mainnet' or 'testnet').
* @param logger Logger instance.
* @param exemptAccounts Optional array of account IDs exempt from this fee.
* @param decimals Optional decimals for the token (fetched if omitted).
* @returns A Promise resolving to a configured FeeConfigBuilder instance.
*/
static async forToken(tokenAmount, feeTokenId, collectorAccountId, network, logger, exemptAccounts = [], decimals) {
const builder = new FeeConfigBuilder({
network,
logger,
defaultCollectorAccountId: collectorAccountId
});
await builder.addTokenFee(
tokenAmount,
feeTokenId,
collectorAccountId,
decimals,
exemptAccounts
);
return builder;
}
/**
* Adds an HBAR fee configuration to the builder.
* Allows chaining multiple fee additions.
* @param hbarAmount The amount in HBAR (e.g., 0.5).
* @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.
* @param exemptAccountIds Optional. Accounts specifically exempt from *this* HBAR fee.
* @returns This FeeConfigBuilder instance for chaining.
*/
addHbarFee(hbarAmount, collectorAccountId, exemptAccountIds = []) {
if (hbarAmount <= 0) {
throw new Error("HBAR amount must be greater than zero");
}
this.customFees.push({
feeAmount: {
amount: hbarAmount * 1e8,
decimals: 0
},
feeCollectorAccountId: collectorAccountId || "",
feeTokenId: void 0,
exemptAccounts: [...exemptAccountIds],
type: CustomFeeType.FIXED_FEE
});
return this;
}
/**
* Adds a token fee configuration to the builder.
* Allows chaining multiple fee additions.
* Fetches token decimals automatically if not provided.
* @param tokenAmount The amount of the specified token.
* @param feeTokenId The ID of the token to charge the fee in.
* @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.
* @param decimals Optional. The number of decimals for the token. If omitted, it will be fetched from the mirror node.
* @param exemptAccountIds Optional. Accounts specifically exempt from *this* token fee.
* @returns A Promise resolving to this FeeConfigBuilder instance for chaining.
*/
async addTokenFee(tokenAmount, feeTokenId, collectorAccountId, decimals, exemptAccountIds = []) {
if (tokenAmount <= 0) {
throw new Error("Token amount must be greater than zero");
}
if (!feeTokenId) {
throw new Error("Fee token ID is required when adding a token fee");
}
let finalDecimals = decimals;
if (finalDecimals === void 0) {
try {
const tokenInfo = await this.mirrorNode.getTokenInfo(feeTokenId);
if (tokenInfo?.decimals) {
finalDecimals = parseInt(tokenInfo.decimals, 10);
this.logger.info(
`Fetched decimals for ${feeTokenId}: ${finalDecimals}`
);
} else {
this.logger.warn(
`Could not fetch decimals for ${feeTokenId}, defaulting to 0.`
);
finalDecimals = 0;
}
} catch (error) {
this.logger.error(
`Error fetching decimals for ${feeTokenId}, defaulting to 0: ${error}`
);
finalDecimals = 0;
}
}
this.customFees.push({
feeAmount: {
amount: tokenAmount * 10 ** finalDecimals,
decimals: finalDecimals
},
feeCollectorAccountId: collectorAccountId || "",
feeTokenId,
exemptAccounts: [...exemptAccountIds],
type: CustomFeeType.FIXED_FEE
});
return this;
}
/**
* Builds the final TopicFeeConfig object.
* @returns The TopicFeeConfig containing all added custom fees and a consolidated list of unique exempt accounts.
* @throws Error if no fees have been added.
* @throws Error if more than 10 fees have been added.
*/
build() {
if (this.customFees.length === 0) {
throw new Error(
"At least one fee must be added using addHbarFee/addTokenFee or created using forHbar/forToken"
);
}
if (this.customFees.length > 10) {
throw new Error("Maximum of 10 custom fees per topic allowed");
}
const allExemptAccounts = /* @__PURE__ */ new Set();
this.customFees.forEach((fee) => {
fee.exemptAccounts.forEach((account) => allExemptAccounts.add(account));
});
return {
customFees: this.customFees,
exemptAccounts: Array.from(allExemptAccounts)
};
}
}
export {
FeeConfigBuilder
};
//# sourceMappingURL=standards-sdk.es30.js.map