@hashgraphonline/standards-sdk 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/hcs-10/agent-builder.d.ts +21 -3
- package/dist/es/hcs-10/base-client.d.ts +2 -3
- package/dist/es/hcs-10/fee-config-builder.d.ts +66 -0
- package/dist/es/hcs-10/sdk.d.ts +10 -3
- package/dist/es/index.d.ts +1 -0
- package/dist/es/services/index.d.ts +1 -0
- package/dist/es/{utils/mirror-node-utils.d.ts → services/mirror-node.d.ts} +10 -7
- package/dist/es/standards-sdk.es.js +208 -81
- package/dist/es/standards-sdk.es.js.map +1 -1
- package/dist/es/utils/index.d.ts +0 -1
- package/dist/umd/hcs-10/agent-builder.d.ts +21 -3
- package/dist/umd/hcs-10/base-client.d.ts +2 -3
- package/dist/umd/hcs-10/fee-config-builder.d.ts +66 -0
- package/dist/umd/hcs-10/sdk.d.ts +10 -3
- package/dist/umd/index.d.ts +1 -0
- package/dist/umd/services/index.d.ts +1 -0
- package/dist/umd/{utils/mirror-node-utils.d.ts → services/mirror-node.d.ts} +10 -7
- package/dist/umd/standards-sdk.umd.js +13 -13
- package/dist/umd/standards-sdk.umd.js.map +1 -1
- package/dist/umd/utils/index.d.ts +0 -1
- package/package.json +2 -1
- package/dist/es/hcs-10/types.d.ts +0 -11
- package/dist/umd/hcs-10/types.d.ts +0 -11
|
@@ -1,7 +1,25 @@
|
|
|
1
|
-
import { InboundTopicType, NetworkType,
|
|
1
|
+
import { InboundTopicType, NetworkType, FeeConfigBuilderInterface, AgentConfiguration } from './types.d';
|
|
2
2
|
import { AIAgentCapability } from '../hcs-11';
|
|
3
3
|
import { AgentMetadata } from './sdk';
|
|
4
4
|
type SocialPlatform = 'twitter' | 'discord' | 'github' | 'website' | 'x' | 'linkedin' | 'youtube' | 'telegram';
|
|
5
|
+
/**
|
|
6
|
+
* AgentBuilder is a builder class for creating agent configurations.
|
|
7
|
+
* It provides a fluent interface for setting various properties of the agent.
|
|
8
|
+
*
|
|
9
|
+
* Example usage:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const agentBuilder = new AgentBuilder();
|
|
12
|
+
* agentBuilder.setName('My Agent');
|
|
13
|
+
* agentBuilder.setDescription('This is my agent');
|
|
14
|
+
* agentBuilder.setCapabilities([AIAgentCapability.CREATE_CONTENT]);
|
|
15
|
+
* agentBuilder.setModel('gpt-4o');
|
|
16
|
+
* agentBuilder.setCreator('John Doe');
|
|
17
|
+
* agentBuilder.addSocial('twitter', 'JohnDoe');
|
|
18
|
+
* agentBuilder.addProperty('key', 'value');
|
|
19
|
+
* const agentConfig = agentBuilder.build();
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
5
23
|
export declare class AgentBuilder {
|
|
6
24
|
private config;
|
|
7
25
|
setName(name: string): AgentBuilder;
|
|
@@ -16,8 +34,8 @@ export declare class AgentBuilder {
|
|
|
16
34
|
setProfilePicture(pfpBuffer: Buffer, pfpFileName: string): AgentBuilder;
|
|
17
35
|
setNetwork(network: NetworkType): AgentBuilder;
|
|
18
36
|
setInboundTopicType(inboundTopicType: InboundTopicType): AgentBuilder;
|
|
19
|
-
setFeeConfig(
|
|
20
|
-
setConnectionFeeConfig(
|
|
37
|
+
setFeeConfig(feeConfigBuilder: FeeConfigBuilderInterface): AgentBuilder;
|
|
38
|
+
setConnectionFeeConfig(feeConfigBuilder: FeeConfigBuilderInterface): AgentBuilder;
|
|
21
39
|
setExistingAccount(accountId: string, privateKey: string): AgentBuilder;
|
|
22
40
|
build(): AgentConfiguration;
|
|
23
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Logger, LogLevel } from '../utils/logger';
|
|
2
2
|
import { Registration } from './registrations';
|
|
3
|
-
import { HederaMirrorNode, TopicInfo, AccountResponse } from '../
|
|
3
|
+
import { HederaMirrorNode, TopicInfo, AccountResponse } from '../services/mirror-node';
|
|
4
4
|
export interface HCS10Config {
|
|
5
5
|
network: 'mainnet' | 'testnet';
|
|
6
6
|
logLevel?: LogLevel;
|
|
@@ -42,8 +42,7 @@ export declare abstract class HCS10BaseClient extends Registration {
|
|
|
42
42
|
getAccountMemo(accountId: string): Promise<string | null>;
|
|
43
43
|
protected getTopicInfoFromMemo(memo: string): Promise<TopicInfo | null>;
|
|
44
44
|
getTopicInfo(accountId: string): Promise<TopicInfo | null>;
|
|
45
|
-
retrieveOutboundConnectTopic(accountId: string): Promise<
|
|
46
|
-
retrieveOutboundConnectTopicFromNetwork(accountId: string): Promise<TopicInfo>;
|
|
45
|
+
retrieveOutboundConnectTopic(accountId: string): Promise<TopicInfo>;
|
|
47
46
|
retrieveOutboundMessages(agentAccountId: string): Promise<HCSMessage[]>;
|
|
48
47
|
hasConnectionCreated(agentAccountId: string, connectionId: number): Promise<boolean>;
|
|
49
48
|
clearCache(): void;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { FeeConfigBuilderInterface, TopicFeeConfig } from './types.d';
|
|
2
|
+
/**
|
|
3
|
+
* FeeConfigBuilder provides a fluent interface for creating fee configurations
|
|
4
|
+
* for HCS-10 topics. This makes it easy to configure fees without dealing with
|
|
5
|
+
* the complexity of the underlying fee structure.
|
|
6
|
+
*
|
|
7
|
+
* Example usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const feeConfig = new FeeConfigBuilder()
|
|
10
|
+
* .setHbarAmount(1) // 1 HBAR
|
|
11
|
+
* .setFeeCollector('0.0.12345')
|
|
12
|
+
* .addExemptAccount('0.0.67890')
|
|
13
|
+
* .build();
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare class FeeConfigBuilder implements FeeConfigBuilderInterface {
|
|
17
|
+
private feeAmount;
|
|
18
|
+
private decimals;
|
|
19
|
+
private feeCollectorAccountId;
|
|
20
|
+
private exemptAccountIds;
|
|
21
|
+
/**
|
|
22
|
+
* Static factory method to create a fee config with HBAR amount in one line
|
|
23
|
+
* @param hbarAmount Amount in HBAR
|
|
24
|
+
* @param collectorAccountId Account that will receive the fees
|
|
25
|
+
* @param exemptAccounts Optional array of exempt account IDs
|
|
26
|
+
* @returns A configured FeeConfigBuilder
|
|
27
|
+
*/
|
|
28
|
+
static forHbar(hbarAmount: number, collectorAccountId: string, exemptAccounts?: string[]): FeeConfigBuilder;
|
|
29
|
+
/**
|
|
30
|
+
* Sets the fee amount in HBAR (convenient method)
|
|
31
|
+
* @param hbarAmount The amount in HBAR (e.g., 5 for 5 HBAR)
|
|
32
|
+
* @returns This builder instance for method chaining
|
|
33
|
+
*/
|
|
34
|
+
setHbarAmount(hbarAmount: number): FeeConfigBuilder;
|
|
35
|
+
/**
|
|
36
|
+
* Sets the amount of the fee to be collected for topic submissions
|
|
37
|
+
* @param amount The fee amount (in tinybars or token units)
|
|
38
|
+
* @param decimals Decimal places for fixed point representation (default: 0)
|
|
39
|
+
* @returns This builder instance for method chaining
|
|
40
|
+
*/
|
|
41
|
+
setFeeAmount(amount: number, decimals?: number): FeeConfigBuilder;
|
|
42
|
+
/**
|
|
43
|
+
* Sets the Hedera account ID that will collect the fees
|
|
44
|
+
* @param accountId The fee collector's account ID (e.g., '0.0.12345')
|
|
45
|
+
* @returns This builder instance for method chaining
|
|
46
|
+
*/
|
|
47
|
+
setFeeCollector(accountId: string): FeeConfigBuilder;
|
|
48
|
+
/**
|
|
49
|
+
* Adds an account ID to the list of accounts exempt from paying fees
|
|
50
|
+
* @param accountId The account ID to exempt from fees
|
|
51
|
+
* @returns This builder instance for method chaining
|
|
52
|
+
*/
|
|
53
|
+
addExemptAccount(accountId: string): FeeConfigBuilder;
|
|
54
|
+
/**
|
|
55
|
+
* Adds multiple account IDs to the list of accounts exempt from paying fees
|
|
56
|
+
* @param accountIds Array of account IDs to exempt from fees
|
|
57
|
+
* @returns This builder instance for method chaining
|
|
58
|
+
*/
|
|
59
|
+
addExemptAccounts(accountIds: string[]): FeeConfigBuilder;
|
|
60
|
+
/**
|
|
61
|
+
* Builds and returns the final fee configuration object
|
|
62
|
+
* @throws Error if fee collector account ID is not set or if fee amount is not positive
|
|
63
|
+
* @returns A complete TopicFeeConfig object
|
|
64
|
+
*/
|
|
65
|
+
build(): TopicFeeConfig;
|
|
66
|
+
}
|
package/dist/es/hcs-10/sdk.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { Client, PrivateKey, KeyList, TransactionReceipt, PublicKey } from '@has
|
|
|
2
2
|
import { RetrievedInscriptionResult } from '@kiloscribe/inscription-sdk';
|
|
3
3
|
import { Logger } from '../utils/logger';
|
|
4
4
|
import { HCS10BaseClient } from './base-client';
|
|
5
|
-
import { HCSClientConfig, AgentConfig, CreateAccountResponse, CreateAgentResponse, InscribePfpResponse, StoreHCS11ProfileResponse, AgentRegistrationResult, HandleConnectionRequestResponse, WaitForConnectionConfirmationResponse, GetAccountAndSignerResponse, InboundTopicType, TopicFeeConfig } from './types.d';
|
|
5
|
+
import { HCSClientConfig, AgentConfig, CreateAccountResponse, CreateAgentResponse, InscribePfpResponse, StoreHCS11ProfileResponse, AgentRegistrationResult, HandleConnectionRequestResponse, WaitForConnectionConfirmationResponse, GetAccountAndSignerResponse, InboundTopicType, TopicFeeConfig, FeeConfigBuilderInterface } from './types.d';
|
|
6
6
|
import { AgentBuilder } from './agent-builder';
|
|
7
7
|
export { InboundTopicType } from './types.d';
|
|
8
|
+
export { FeeConfigBuilder } from './fee-config-builder';
|
|
8
9
|
export interface AgentMetadata {
|
|
9
10
|
type: 'autonomous' | 'manual';
|
|
10
11
|
model?: string;
|
|
@@ -43,7 +44,7 @@ export declare class HCS10Client extends HCS10BaseClient {
|
|
|
43
44
|
* @param feeConfig Optional fee configuration for fee-based topics
|
|
44
45
|
* @returns The topic ID of the created inbound topic
|
|
45
46
|
*/
|
|
46
|
-
createInboundTopic(accountId: string, topicType: InboundTopicType, feeConfig?:
|
|
47
|
+
createInboundTopic(accountId: string, topicType: InboundTopicType, feeConfig?: FeeConfigBuilderInterface): Promise<string>;
|
|
47
48
|
/**
|
|
48
49
|
* Creates a new agent with inbound and outbound topics
|
|
49
50
|
* @param builder The agent builder object
|
|
@@ -79,7 +80,7 @@ export declare class HCS10Client extends HCS10BaseClient {
|
|
|
79
80
|
* @param connectionFeeConfig Optional fee configuration for the connection topic
|
|
80
81
|
* @returns Response with connection details
|
|
81
82
|
*/
|
|
82
|
-
handleConnectionRequest(inboundTopicId: string, requestingAccountId: string, connectionRequestId: number, connectionFeeConfig?:
|
|
83
|
+
handleConnectionRequest(inboundTopicId: string, requestingAccountId: string, connectionRequestId: number, connectionFeeConfig?: FeeConfigBuilderInterface): Promise<HandleConnectionRequestResponse>;
|
|
83
84
|
confirmConnection(inboundTopicId: string, connectionTopicId: string, connectedAccountId: string, connectionId: number, operatorId: string, memo: string, submitKey?: PrivateKey): Promise<number>;
|
|
84
85
|
sendMessage(connectionTopicId: string, operatorId: string, data: string, memo?: string, submitKey?: PrivateKey): Promise<void>;
|
|
85
86
|
createTopic(memo: string, adminKey?: boolean | PublicKey | KeyList, submitKey?: boolean | PublicKey | KeyList, feeConfig?: TopicFeeConfig): Promise<string>;
|
|
@@ -105,6 +106,12 @@ export declare class HCS10Client extends HCS10BaseClient {
|
|
|
105
106
|
*/
|
|
106
107
|
waitForConnectionConfirmation(inboundTopicId: string, connectionRequestId: number, maxAttempts?: number, delayMs?: number): Promise<WaitForConnectionConfirmationResponse>;
|
|
107
108
|
getAccountAndSigner(): GetAccountAndSignerResponse;
|
|
109
|
+
/**
|
|
110
|
+
* Checks if a user can submit to a topic and determines if a fee is required
|
|
111
|
+
* @param topicId The topic ID to check
|
|
112
|
+
* @param userAccountId The account ID of the user attempting to submit
|
|
113
|
+
* @returns Object with canSubmit, requiresFee, and optional reason
|
|
114
|
+
*/
|
|
108
115
|
canSubmitToInboundTopic(topicId: string, userAccountId: string): Promise<{
|
|
109
116
|
canSubmit: boolean;
|
|
110
117
|
requiresFee: boolean;
|
package/dist/es/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './mirror-node';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PublicKey } from '@hashgraph/sdk';
|
|
2
|
-
import { Logger } from '
|
|
2
|
+
import { Logger } from '../utils/logger';
|
|
3
3
|
import { HCSMessage } from '../hcs-10/base-client';
|
|
4
4
|
export interface Balance {
|
|
5
5
|
balance: number;
|
|
@@ -99,20 +99,20 @@ export interface TopicMessagesResponse {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
export interface TopicResponse {
|
|
102
|
-
admin_key:
|
|
102
|
+
admin_key: Key;
|
|
103
103
|
auto_renew_account: string;
|
|
104
104
|
auto_renew_period: number;
|
|
105
105
|
created_timestamp: string;
|
|
106
106
|
custom_fees: CustomFees;
|
|
107
107
|
deleted: boolean;
|
|
108
|
-
fee_exempt_key_list:
|
|
109
|
-
fee_schedule_key:
|
|
108
|
+
fee_exempt_key_list: Key[];
|
|
109
|
+
fee_schedule_key: Key;
|
|
110
110
|
memo: string;
|
|
111
|
-
submit_key:
|
|
111
|
+
submit_key: Key;
|
|
112
112
|
timestamp: Timestamp;
|
|
113
113
|
topic_id: string;
|
|
114
114
|
}
|
|
115
|
-
export interface
|
|
115
|
+
export interface Key {
|
|
116
116
|
_type: string;
|
|
117
117
|
key: string;
|
|
118
118
|
}
|
|
@@ -142,5 +142,8 @@ export declare class HederaMirrorNode {
|
|
|
142
142
|
getTopicFees(topicId: string): Promise<CustomFees | null>;
|
|
143
143
|
getTopicMessages(topicId: string): Promise<HCSMessage[]>;
|
|
144
144
|
requestAccount(accountId: string): Promise<AccountResponse>;
|
|
145
|
-
|
|
145
|
+
checkKeyListAccess(keyBytes: Buffer, userPublicKey: PublicKey): Promise<boolean>;
|
|
146
|
+
private evaluateKeyAccess;
|
|
147
|
+
private evaluateKeyList;
|
|
148
|
+
private compareEd25519Key;
|
|
146
149
|
}
|
|
@@ -19,6 +19,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
|
|
|
19
19
|
});
|
|
20
20
|
var _names, _data, _dataLength, _Writer_instances, writeData_fn, _data2, _offset, _bytesRead, _parent, _maxInflation, _Reader_instances, incrementBytesRead_fn, peekBytes_fn, _options, _offset2, _tokens, _TokenString_instances, subTokenString_fn, _ParamType_instances, walkAsync_fn, _AbiCoder_instances, getCoder_fn, _errors, _events, _functions, _abiCoder, _Interface_instances, getFunction_fn, getEvent_fn;
|
|
21
21
|
import { ContractId, AccountId, Client, PrivateKey, Transaction, PublicKey, Status, AccountUpdateTransaction, AccountCreateTransaction, Hbar, CustomFixedFee, KeyList, TopicCreateTransaction, TopicMessageSubmitTransaction, TopicId } from "@hashgraph/sdk";
|
|
22
|
+
import { proto } from "@hashgraph/proto";
|
|
22
23
|
let Logger$1 = class Logger {
|
|
23
24
|
constructor(options = {}) {
|
|
24
25
|
this.level = options.level || "info";
|
|
@@ -6223,11 +6224,11 @@ ieee754$1.write = function(buffer2, value, offset, isLE2, mLen, nBytes) {
|
|
|
6223
6224
|
function typedArraySupport() {
|
|
6224
6225
|
try {
|
|
6225
6226
|
const arr = new GlobalUint8Array(1);
|
|
6226
|
-
const
|
|
6227
|
+
const proto2 = { foo: function() {
|
|
6227
6228
|
return 42;
|
|
6228
6229
|
} };
|
|
6229
|
-
Object.setPrototypeOf(
|
|
6230
|
-
Object.setPrototypeOf(arr,
|
|
6230
|
+
Object.setPrototypeOf(proto2, GlobalUint8Array.prototype);
|
|
6231
|
+
Object.setPrototypeOf(arr, proto2);
|
|
6231
6232
|
return arr.foo() === 42;
|
|
6232
6233
|
} catch (e) {
|
|
6233
6234
|
return false;
|
|
@@ -8017,11 +8018,11 @@ ieee754.write = function(buffer2, value, offset, isLE2, mLen, nBytes) {
|
|
|
8017
8018
|
function typedArraySupport() {
|
|
8018
8019
|
try {
|
|
8019
8020
|
const arr = new GlobalUint8Array(1);
|
|
8020
|
-
const
|
|
8021
|
+
const proto2 = { foo: function() {
|
|
8021
8022
|
return 42;
|
|
8022
8023
|
} };
|
|
8023
|
-
Object.setPrototypeOf(
|
|
8024
|
-
Object.setPrototypeOf(arr,
|
|
8024
|
+
Object.setPrototypeOf(proto2, GlobalUint8Array.prototype);
|
|
8025
|
+
Object.setPrototypeOf(arr, proto2);
|
|
8025
8026
|
return arr.foo() === 42;
|
|
8026
8027
|
} catch (e) {
|
|
8027
8028
|
return false;
|
|
@@ -15496,10 +15497,8 @@ class HederaMirrorNode {
|
|
|
15496
15497
|
if (this.logger) {
|
|
15497
15498
|
this.logger.info(`Getting public key for account ${accountId}`);
|
|
15498
15499
|
}
|
|
15499
|
-
const
|
|
15500
|
+
const accountInfo = await this.requestAccount(accountId);
|
|
15500
15501
|
try {
|
|
15501
|
-
const response = await axios.get(accountInfoUrl);
|
|
15502
|
-
const accountInfo = response.data;
|
|
15503
15502
|
if (!accountInfo || !accountInfo.key) {
|
|
15504
15503
|
throw new Error(
|
|
15505
15504
|
`Failed to retrieve public key for account ID: ${accountId}`
|
|
@@ -15514,11 +15513,9 @@ class HederaMirrorNode {
|
|
|
15514
15513
|
}
|
|
15515
15514
|
async getAccountMemo(accountId) {
|
|
15516
15515
|
try {
|
|
15517
|
-
const
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
if (response.data && response.data.memo) {
|
|
15521
|
-
return response.data.memo;
|
|
15516
|
+
const accountInfo = await this.requestAccount(accountId);
|
|
15517
|
+
if (accountInfo && accountInfo.memo) {
|
|
15518
|
+
return accountInfo.memo;
|
|
15522
15519
|
}
|
|
15523
15520
|
return null;
|
|
15524
15521
|
} catch (error) {
|
|
@@ -15611,20 +15608,65 @@ class HederaMirrorNode {
|
|
|
15611
15608
|
throw new Error(`Failed to fetch account: ${error.message}`);
|
|
15612
15609
|
}
|
|
15613
15610
|
}
|
|
15614
|
-
async
|
|
15611
|
+
async checkKeyListAccess(keyBytes, userPublicKey) {
|
|
15615
15612
|
try {
|
|
15616
|
-
const
|
|
15617
|
-
|
|
15618
|
-
return response.data;
|
|
15613
|
+
const key = proto.Key.decode(keyBytes);
|
|
15614
|
+
return this.evaluateKeyAccess(key, userPublicKey);
|
|
15619
15615
|
} catch (error) {
|
|
15620
15616
|
if (this.logger) {
|
|
15621
|
-
this.logger.error(
|
|
15622
|
-
`Error retrieving account information: ${error.message}`
|
|
15623
|
-
);
|
|
15617
|
+
this.logger.error(`Error decoding protobuf key: ${error instanceof Error ? error.message : String(error)}`);
|
|
15624
15618
|
}
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15619
|
+
return false;
|
|
15620
|
+
}
|
|
15621
|
+
}
|
|
15622
|
+
async evaluateKeyAccess(key, userPublicKey) {
|
|
15623
|
+
if (key.ed25519) {
|
|
15624
|
+
return this.compareEd25519Key(key.ed25519, userPublicKey);
|
|
15625
|
+
}
|
|
15626
|
+
if (key.keyList) {
|
|
15627
|
+
return this.evaluateKeyList(key.keyList, userPublicKey);
|
|
15628
|
+
}
|
|
15629
|
+
if (key.thresholdKey && key.thresholdKey.keys) {
|
|
15630
|
+
return this.evaluateKeyList(key.thresholdKey.keys, userPublicKey);
|
|
15631
|
+
}
|
|
15632
|
+
return false;
|
|
15633
|
+
}
|
|
15634
|
+
async evaluateKeyList(keyList, userPublicKey) {
|
|
15635
|
+
const keys = keyList.keys || [];
|
|
15636
|
+
for (const listKey of keys) {
|
|
15637
|
+
if (!listKey) continue;
|
|
15638
|
+
if (listKey.ed25519) {
|
|
15639
|
+
if (this.compareEd25519Key(listKey.ed25519, userPublicKey)) {
|
|
15640
|
+
return true;
|
|
15641
|
+
}
|
|
15642
|
+
} else if (listKey.keyList || listKey.thresholdKey) {
|
|
15643
|
+
try {
|
|
15644
|
+
const nestedKeyBytes = proto.Key.encode({
|
|
15645
|
+
...listKey.keyList ? { keyList: listKey.keyList } : {},
|
|
15646
|
+
...listKey.thresholdKey ? { thresholdKey: listKey.thresholdKey } : {}
|
|
15647
|
+
}).finish();
|
|
15648
|
+
const hasNestedAccess = await this.checkKeyListAccess(
|
|
15649
|
+
Buffer2.from(nestedKeyBytes),
|
|
15650
|
+
userPublicKey
|
|
15651
|
+
);
|
|
15652
|
+
if (hasNestedAccess) {
|
|
15653
|
+
return true;
|
|
15654
|
+
}
|
|
15655
|
+
} catch (err) {
|
|
15656
|
+
if (this.logger) {
|
|
15657
|
+
this.logger.debug(`Error in nested key: ${err instanceof Error ? err.message : String(err)}`);
|
|
15658
|
+
}
|
|
15659
|
+
}
|
|
15660
|
+
}
|
|
15661
|
+
}
|
|
15662
|
+
return false;
|
|
15663
|
+
}
|
|
15664
|
+
compareEd25519Key(keyData, userPublicKey) {
|
|
15665
|
+
try {
|
|
15666
|
+
const decodedKey = PublicKey.fromBytes(Buffer2.from(keyData));
|
|
15667
|
+
return decodedKey.toString() === userPublicKey.toString();
|
|
15668
|
+
} catch (err) {
|
|
15669
|
+
return false;
|
|
15628
15670
|
}
|
|
15629
15671
|
}
|
|
15630
15672
|
}
|
|
@@ -15705,10 +15747,6 @@ class HCS10BaseClient extends Registration {
|
|
|
15705
15747
|
return topicInfo;
|
|
15706
15748
|
}
|
|
15707
15749
|
async retrieveOutboundConnectTopic(accountId) {
|
|
15708
|
-
const topicInfo = await this.getTopicInfo(accountId);
|
|
15709
|
-
return (topicInfo == null ? void 0 : topicInfo.outboundTopic) ?? null;
|
|
15710
|
-
}
|
|
15711
|
-
async retrieveOutboundConnectTopicFromNetwork(accountId) {
|
|
15712
15750
|
this.logger.info(`Retrieving topics for account: ${accountId}`);
|
|
15713
15751
|
const cachedInfo = await this.getTopicInfo(accountId);
|
|
15714
15752
|
if (cachedInfo) return cachedInfo;
|
|
@@ -15759,7 +15797,7 @@ class HCS10BaseClient extends Registration {
|
|
|
15759
15797
|
}
|
|
15760
15798
|
async retrieveOutboundMessages(agentAccountId) {
|
|
15761
15799
|
try {
|
|
15762
|
-
const topicInfo = await this.
|
|
15800
|
+
const topicInfo = await this.retrieveOutboundConnectTopic(
|
|
15763
15801
|
agentAccountId
|
|
15764
15802
|
);
|
|
15765
15803
|
if (!topicInfo) {
|
|
@@ -15779,7 +15817,7 @@ class HCS10BaseClient extends Registration {
|
|
|
15779
15817
|
}
|
|
15780
15818
|
async hasConnectionCreated(agentAccountId, connectionId) {
|
|
15781
15819
|
try {
|
|
15782
|
-
const outBoundTopic = await this.
|
|
15820
|
+
const outBoundTopic = await this.retrieveOutboundConnectTopic(
|
|
15783
15821
|
agentAccountId
|
|
15784
15822
|
);
|
|
15785
15823
|
const messages = await this.retrieveOutboundMessages(
|
|
@@ -31894,6 +31932,100 @@ async function accountIdsToExemptKeys(accountIds, network, logger) {
|
|
|
31894
31932
|
}
|
|
31895
31933
|
return exemptKeys;
|
|
31896
31934
|
}
|
|
31935
|
+
class FeeConfigBuilder {
|
|
31936
|
+
constructor() {
|
|
31937
|
+
this.feeAmount = 0;
|
|
31938
|
+
this.decimals = 0;
|
|
31939
|
+
this.feeCollectorAccountId = "";
|
|
31940
|
+
this.exemptAccountIds = [];
|
|
31941
|
+
}
|
|
31942
|
+
/**
|
|
31943
|
+
* Static factory method to create a fee config with HBAR amount in one line
|
|
31944
|
+
* @param hbarAmount Amount in HBAR
|
|
31945
|
+
* @param collectorAccountId Account that will receive the fees
|
|
31946
|
+
* @param exemptAccounts Optional array of exempt account IDs
|
|
31947
|
+
* @returns A configured FeeConfigBuilder
|
|
31948
|
+
*/
|
|
31949
|
+
static forHbar(hbarAmount, collectorAccountId, exemptAccounts = []) {
|
|
31950
|
+
return new FeeConfigBuilder().setHbarAmount(hbarAmount).setFeeCollector(collectorAccountId).addExemptAccounts(exemptAccounts);
|
|
31951
|
+
}
|
|
31952
|
+
/**
|
|
31953
|
+
* Sets the fee amount in HBAR (convenient method)
|
|
31954
|
+
* @param hbarAmount The amount in HBAR (e.g., 5 for 5 HBAR)
|
|
31955
|
+
* @returns This builder instance for method chaining
|
|
31956
|
+
*/
|
|
31957
|
+
setHbarAmount(hbarAmount) {
|
|
31958
|
+
if (hbarAmount <= 0) {
|
|
31959
|
+
throw new Error("HBAR amount must be greater than zero");
|
|
31960
|
+
}
|
|
31961
|
+
this.feeAmount = hbarAmount * 1e8;
|
|
31962
|
+
this.decimals = 0;
|
|
31963
|
+
return this;
|
|
31964
|
+
}
|
|
31965
|
+
/**
|
|
31966
|
+
* Sets the amount of the fee to be collected for topic submissions
|
|
31967
|
+
* @param amount The fee amount (in tinybars or token units)
|
|
31968
|
+
* @param decimals Decimal places for fixed point representation (default: 0)
|
|
31969
|
+
* @returns This builder instance for method chaining
|
|
31970
|
+
*/
|
|
31971
|
+
setFeeAmount(amount, decimals = 0) {
|
|
31972
|
+
this.feeAmount = amount;
|
|
31973
|
+
this.decimals = decimals;
|
|
31974
|
+
return this;
|
|
31975
|
+
}
|
|
31976
|
+
/**
|
|
31977
|
+
* Sets the Hedera account ID that will collect the fees
|
|
31978
|
+
* @param accountId The fee collector's account ID (e.g., '0.0.12345')
|
|
31979
|
+
* @returns This builder instance for method chaining
|
|
31980
|
+
*/
|
|
31981
|
+
setFeeCollector(accountId) {
|
|
31982
|
+
this.feeCollectorAccountId = accountId;
|
|
31983
|
+
return this;
|
|
31984
|
+
}
|
|
31985
|
+
/**
|
|
31986
|
+
* Adds an account ID to the list of accounts exempt from paying fees
|
|
31987
|
+
* @param accountId The account ID to exempt from fees
|
|
31988
|
+
* @returns This builder instance for method chaining
|
|
31989
|
+
*/
|
|
31990
|
+
addExemptAccount(accountId) {
|
|
31991
|
+
if (!this.exemptAccountIds.includes(accountId)) {
|
|
31992
|
+
this.exemptAccountIds.push(accountId);
|
|
31993
|
+
}
|
|
31994
|
+
return this;
|
|
31995
|
+
}
|
|
31996
|
+
/**
|
|
31997
|
+
* Adds multiple account IDs to the list of accounts exempt from paying fees
|
|
31998
|
+
* @param accountIds Array of account IDs to exempt from fees
|
|
31999
|
+
* @returns This builder instance for method chaining
|
|
32000
|
+
*/
|
|
32001
|
+
addExemptAccounts(accountIds) {
|
|
32002
|
+
for (const accountId of accountIds) {
|
|
32003
|
+
this.addExemptAccount(accountId);
|
|
32004
|
+
}
|
|
32005
|
+
return this;
|
|
32006
|
+
}
|
|
32007
|
+
/**
|
|
32008
|
+
* Builds and returns the final fee configuration object
|
|
32009
|
+
* @throws Error if fee collector account ID is not set or if fee amount is not positive
|
|
32010
|
+
* @returns A complete TopicFeeConfig object
|
|
32011
|
+
*/
|
|
32012
|
+
build() {
|
|
32013
|
+
if (!this.feeCollectorAccountId) {
|
|
32014
|
+
throw new Error("Fee collector account ID is required");
|
|
32015
|
+
}
|
|
32016
|
+
if (this.feeAmount <= 0) {
|
|
32017
|
+
throw new Error("Fee amount must be greater than zero");
|
|
32018
|
+
}
|
|
32019
|
+
return {
|
|
32020
|
+
feeAmount: {
|
|
32021
|
+
amount: this.feeAmount,
|
|
32022
|
+
decimals: this.decimals
|
|
32023
|
+
},
|
|
32024
|
+
feeCollectorAccountId: this.feeCollectorAccountId,
|
|
32025
|
+
exemptAccounts: this.exemptAccountIds
|
|
32026
|
+
};
|
|
32027
|
+
}
|
|
32028
|
+
}
|
|
31897
32029
|
class HCS10Client extends HCS10BaseClient {
|
|
31898
32030
|
constructor(config) {
|
|
31899
32031
|
super({
|
|
@@ -31970,7 +32102,7 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
31970
32102
|
if (!feeConfig) {
|
|
31971
32103
|
throw new Error("Fee configuration is required for fee-based topics");
|
|
31972
32104
|
}
|
|
31973
|
-
return this.createTopic(memo, true, true, feeConfig);
|
|
32105
|
+
return this.createTopic(memo, true, true, feeConfig.build());
|
|
31974
32106
|
default:
|
|
31975
32107
|
throw new Error(`Unsupported inbound topic type: ${topicType}`);
|
|
31976
32108
|
}
|
|
@@ -32147,6 +32279,7 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32147
32279
|
...feeConfig.exemptAccounts || [],
|
|
32148
32280
|
...additionalExemptAccounts
|
|
32149
32281
|
];
|
|
32282
|
+
console.log("exemptAccountIds", exemptAccountIds);
|
|
32150
32283
|
if (exemptAccountIds.length > 0) {
|
|
32151
32284
|
const uniqueExemptAccountIds = Array.from(new Set(exemptAccountIds));
|
|
32152
32285
|
const filteredExemptAccounts = uniqueExemptAccountIds.filter(
|
|
@@ -32202,13 +32335,10 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32202
32335
|
let connectionTopicId;
|
|
32203
32336
|
try {
|
|
32204
32337
|
if (connectionFeeConfig) {
|
|
32205
|
-
const
|
|
32338
|
+
const feeConfig = connectionFeeConfig.build();
|
|
32206
32339
|
const modifiedFeeConfig = {
|
|
32207
|
-
...
|
|
32208
|
-
exemptAccounts: [
|
|
32209
|
-
...connectionFeeConfig.exemptAccounts || [],
|
|
32210
|
-
...additionalExemptAccounts
|
|
32211
|
-
]
|
|
32340
|
+
...feeConfig,
|
|
32341
|
+
exemptAccounts: [...feeConfig.exemptAccounts || []]
|
|
32212
32342
|
};
|
|
32213
32343
|
connectionTopicId = await this.createTopic(
|
|
32214
32344
|
memo,
|
|
@@ -32391,7 +32521,7 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32391
32521
|
this.logger.info(
|
|
32392
32522
|
`Submitted connection request to topic ID: ${inboundTopicId}`
|
|
32393
32523
|
);
|
|
32394
|
-
const outboundTopic = await this.
|
|
32524
|
+
const outboundTopic = await this.retrieveOutboundConnectTopic(
|
|
32395
32525
|
requestingAccountId
|
|
32396
32526
|
);
|
|
32397
32527
|
const responseSequenceNumber = (_a = response.topicSequenceNumber) == null ? void 0 : _a.toNumber();
|
|
@@ -32493,27 +32623,15 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32493
32623
|
`Attempt ${attempt + 1}/${maxAttempts} to find connection confirmation`
|
|
32494
32624
|
);
|
|
32495
32625
|
const messages = await this.mirrorNode.getTopicMessages(inboundTopicId);
|
|
32496
|
-
this.logger.info(
|
|
32497
|
-
`Retrieved ${messages.length} messages from topic ${inboundTopicId}`
|
|
32498
|
-
);
|
|
32499
|
-
messages.forEach((msg, index) => {
|
|
32500
|
-
this.logger.info(`Message ${index}: ${JSON.stringify(msg)}`);
|
|
32501
|
-
});
|
|
32502
32626
|
const connectionCreatedMessages = messages.filter(
|
|
32503
32627
|
(m) => m.op === "connection_created"
|
|
32504
32628
|
);
|
|
32505
32629
|
this.logger.info(
|
|
32506
32630
|
`Found ${connectionCreatedMessages.length} connection_created messages`
|
|
32507
32631
|
);
|
|
32508
|
-
connectionCreatedMessages.forEach((msg, index) => {
|
|
32509
|
-
this.logger.info(`Connection message ${index}: ${JSON.stringify(msg)}`);
|
|
32510
|
-
});
|
|
32511
32632
|
if (connectionCreatedMessages.length > 0) {
|
|
32512
32633
|
for (const message of connectionCreatedMessages) {
|
|
32513
|
-
|
|
32514
|
-
`Checking if message connection_id (${message.connection_id}) matches request ID (${connectionRequestId})`
|
|
32515
|
-
);
|
|
32516
|
-
if (message.connection_id === connectionRequestId) {
|
|
32634
|
+
if (Number(message.connection_id) === Number(connectionRequestId)) {
|
|
32517
32635
|
this.logger.info("Connection confirmation found");
|
|
32518
32636
|
return {
|
|
32519
32637
|
connectionTopicId: message.connection_topic_id,
|
|
@@ -32541,7 +32659,14 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32541
32659
|
signer: this.operatorPrivateKey
|
|
32542
32660
|
};
|
|
32543
32661
|
}
|
|
32662
|
+
/**
|
|
32663
|
+
* Checks if a user can submit to a topic and determines if a fee is required
|
|
32664
|
+
* @param topicId The topic ID to check
|
|
32665
|
+
* @param userAccountId The account ID of the user attempting to submit
|
|
32666
|
+
* @returns Object with canSubmit, requiresFee, and optional reason
|
|
32667
|
+
*/
|
|
32544
32668
|
async canSubmitToInboundTopic(topicId, userAccountId) {
|
|
32669
|
+
var _a, _b, _c, _d;
|
|
32545
32670
|
try {
|
|
32546
32671
|
const topicInfo = await this.mirrorNode.getTopicInfo(topicId);
|
|
32547
32672
|
if (!topicInfo) {
|
|
@@ -32551,29 +32676,37 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32551
32676
|
reason: "Topic does not exist"
|
|
32552
32677
|
};
|
|
32553
32678
|
}
|
|
32554
|
-
|
|
32555
|
-
if (!hasSubmitKey) {
|
|
32679
|
+
if (!((_a = topicInfo.submit_key) == null ? void 0 : _a.key)) {
|
|
32556
32680
|
return { canSubmit: true, requiresFee: false };
|
|
32557
32681
|
}
|
|
32558
32682
|
try {
|
|
32559
32683
|
const userPublicKey = await this.mirrorNode.getPublicKey(userAccountId);
|
|
32560
|
-
|
|
32561
|
-
|
|
32562
|
-
|
|
32684
|
+
if (topicInfo.submit_key._type === "ProtobufEncoded") {
|
|
32685
|
+
const keyBytes = Buffer2.from(topicInfo.submit_key.key, "hex");
|
|
32686
|
+
const hasAccess = await this.mirrorNode.checkKeyListAccess(
|
|
32687
|
+
keyBytes,
|
|
32688
|
+
userPublicKey
|
|
32689
|
+
);
|
|
32690
|
+
if (hasAccess) {
|
|
32691
|
+
return { canSubmit: true, requiresFee: false };
|
|
32692
|
+
}
|
|
32693
|
+
} else {
|
|
32694
|
+
const topicSubmitKey = PublicKey.fromString(topicInfo.submit_key.key);
|
|
32695
|
+
if (userPublicKey.toString() === topicSubmitKey.toString()) {
|
|
32696
|
+
return { canSubmit: true, requiresFee: false };
|
|
32697
|
+
}
|
|
32563
32698
|
}
|
|
32564
32699
|
} catch (error) {
|
|
32565
|
-
this.logger.error(
|
|
32700
|
+
this.logger.error(
|
|
32701
|
+
`Key validation error: ${error instanceof Error ? error.message : String(error)}`
|
|
32702
|
+
);
|
|
32566
32703
|
}
|
|
32567
|
-
|
|
32568
|
-
|
|
32569
|
-
|
|
32570
|
-
|
|
32571
|
-
|
|
32572
|
-
|
|
32573
|
-
requiresFee: true,
|
|
32574
|
-
reason: "Requires fee payment via HIP-991"
|
|
32575
|
-
};
|
|
32576
|
-
}
|
|
32704
|
+
if (((_b = topicInfo.fee_schedule_key) == null ? void 0 : _b.key) && ((_d = (_c = topicInfo.custom_fees) == null ? void 0 : _c.fixed_fees) == null ? void 0 : _d.length) > 0) {
|
|
32705
|
+
return {
|
|
32706
|
+
canSubmit: true,
|
|
32707
|
+
requiresFee: true,
|
|
32708
|
+
reason: "Requires fee payment via HIP-991"
|
|
32709
|
+
};
|
|
32577
32710
|
}
|
|
32578
32711
|
return {
|
|
32579
32712
|
canSubmit: false,
|
|
@@ -32581,11 +32714,12 @@ class HCS10Client extends HCS10BaseClient {
|
|
|
32581
32714
|
reason: "User does not have submit permission for this topic"
|
|
32582
32715
|
};
|
|
32583
32716
|
} catch (error) {
|
|
32584
|
-
|
|
32717
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
32718
|
+
this.logger.error(`Topic submission validation error: ${errorMessage}`);
|
|
32585
32719
|
return {
|
|
32586
32720
|
canSubmit: false,
|
|
32587
32721
|
requiresFee: false,
|
|
32588
|
-
reason: `Error: ${
|
|
32722
|
+
reason: `Error: ${errorMessage}`
|
|
32589
32723
|
};
|
|
32590
32724
|
}
|
|
32591
32725
|
}
|
|
@@ -32808,20 +32942,12 @@ class AgentBuilder {
|
|
|
32808
32942
|
this.config.inboundTopicType = inboundTopicType;
|
|
32809
32943
|
return this;
|
|
32810
32944
|
}
|
|
32811
|
-
setFeeConfig(
|
|
32812
|
-
this.config.feeConfig =
|
|
32813
|
-
feeAmount,
|
|
32814
|
-
feeCollectorAccountId,
|
|
32815
|
-
exemptAccounts
|
|
32816
|
-
};
|
|
32945
|
+
setFeeConfig(feeConfigBuilder) {
|
|
32946
|
+
this.config.feeConfig = feeConfigBuilder;
|
|
32817
32947
|
return this;
|
|
32818
32948
|
}
|
|
32819
|
-
setConnectionFeeConfig(
|
|
32820
|
-
this.config.connectionFeeConfig =
|
|
32821
|
-
feeAmount,
|
|
32822
|
-
feeCollectorAccountId,
|
|
32823
|
-
exemptAccounts
|
|
32824
|
-
};
|
|
32949
|
+
setConnectionFeeConfig(feeConfigBuilder) {
|
|
32950
|
+
this.config.connectionFeeConfig = feeConfigBuilder;
|
|
32825
32951
|
return this;
|
|
32826
32952
|
}
|
|
32827
32953
|
setExistingAccount(accountId, privateKey) {
|
|
@@ -32864,6 +32990,7 @@ export {
|
|
|
32864
32990
|
ConnectionConfirmationError,
|
|
32865
32991
|
EVMBridge,
|
|
32866
32992
|
EndpointType,
|
|
32993
|
+
FeeConfigBuilder,
|
|
32867
32994
|
HCS,
|
|
32868
32995
|
HCS10BaseClient,
|
|
32869
32996
|
HCS10Cache,
|