@hashgraphonline/standards-sdk 0.0.17 → 0.0.19
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/index.d.ts +1 -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 +804 -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/index.d.ts +1 -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
|
@@ -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) {
|
|
@@ -32856,14 +32982,611 @@ class AgentBuilder {
|
|
|
32856
32982
|
return this.config;
|
|
32857
32983
|
}
|
|
32858
32984
|
}
|
|
32985
|
+
class BrowserHCSClient extends HCS10BaseClient {
|
|
32986
|
+
constructor(config) {
|
|
32987
|
+
super({
|
|
32988
|
+
network: config.network,
|
|
32989
|
+
logLevel: config.logLevel
|
|
32990
|
+
});
|
|
32991
|
+
this.guardedRegistryBaseUrl = config.guardedRegistryBaseUrl || "https://moonscape.tech";
|
|
32992
|
+
this.hwc = config.hwc;
|
|
32993
|
+
this.logger = Logger$1.getInstance({
|
|
32994
|
+
level: config.logLevel || "info",
|
|
32995
|
+
module: "HCS-Browser"
|
|
32996
|
+
});
|
|
32997
|
+
const { accountId, signer } = this.getAccountAndSigner();
|
|
32998
|
+
this.hcs11Client = new HCS11Client({
|
|
32999
|
+
network: config.network,
|
|
33000
|
+
auth: {
|
|
33001
|
+
operatorId: accountId,
|
|
33002
|
+
signer
|
|
33003
|
+
},
|
|
33004
|
+
logLevel: config.logLevel
|
|
33005
|
+
});
|
|
33006
|
+
}
|
|
33007
|
+
async sendMessage(connectionTopicId, operatorId, data, memo) {
|
|
33008
|
+
this.logger.info("Sending message");
|
|
33009
|
+
const payload = {
|
|
33010
|
+
p: "hcs-10",
|
|
33011
|
+
op: "message",
|
|
33012
|
+
operator_id: operatorId,
|
|
33013
|
+
data,
|
|
33014
|
+
m: memo
|
|
33015
|
+
};
|
|
33016
|
+
await this.submitPayload(connectionTopicId, payload);
|
|
33017
|
+
}
|
|
33018
|
+
async submitConnectionRequest(inboundTopicId, requestingAccountId, operatorId, memo) {
|
|
33019
|
+
var _a, _b;
|
|
33020
|
+
this.logger.info("Submitting connection request");
|
|
33021
|
+
const connectionRequestMessage = {
|
|
33022
|
+
p: "hcs-10",
|
|
33023
|
+
op: "connection_request",
|
|
33024
|
+
requesting_account_id: requestingAccountId,
|
|
33025
|
+
operator_id: operatorId,
|
|
33026
|
+
m: memo
|
|
33027
|
+
};
|
|
33028
|
+
const response = await this.submitPayload(
|
|
33029
|
+
inboundTopicId,
|
|
33030
|
+
connectionRequestMessage
|
|
33031
|
+
);
|
|
33032
|
+
this.logger.info(
|
|
33033
|
+
`Submitted connection request to topic ID: ${inboundTopicId}`
|
|
33034
|
+
);
|
|
33035
|
+
const outboundTopic = await this.retrieveOutboundConnectTopic(
|
|
33036
|
+
requestingAccountId
|
|
33037
|
+
);
|
|
33038
|
+
if (!(outboundTopic == null ? void 0 : outboundTopic.outboundTopic)) {
|
|
33039
|
+
this.logger.error(
|
|
33040
|
+
`Failed to retrieve outbound topic for account ID: ${requestingAccountId}`
|
|
33041
|
+
);
|
|
33042
|
+
throw new Error(
|
|
33043
|
+
`Failed to retrieve outbound topic for account ID: ${requestingAccountId}`
|
|
33044
|
+
);
|
|
33045
|
+
}
|
|
33046
|
+
this.logger.info(
|
|
33047
|
+
`Retrieved outbound topic ID: ${outboundTopic.outboundTopic} for account ID: ${requestingAccountId}`
|
|
33048
|
+
);
|
|
33049
|
+
const responseSequenceNumber = (_b = (_a = response == null ? void 0 : response.result) == null ? void 0 : _a.topicSequenceNumber) == null ? void 0 : _b.toNumber();
|
|
33050
|
+
if (!responseSequenceNumber) {
|
|
33051
|
+
throw new Error("Failed to get response sequence number");
|
|
33052
|
+
}
|
|
33053
|
+
await this.submitPayload(outboundTopic.outboundTopic, {
|
|
33054
|
+
...connectionRequestMessage,
|
|
33055
|
+
outbound_topic_id: inboundTopicId,
|
|
33056
|
+
connection_request_id: responseSequenceNumber
|
|
33057
|
+
});
|
|
33058
|
+
return response.result;
|
|
33059
|
+
}
|
|
33060
|
+
async recordOutboundConnectionConfirmation({
|
|
33061
|
+
outboundTopicId,
|
|
33062
|
+
connectionRequestId,
|
|
33063
|
+
confirmedRequestId,
|
|
33064
|
+
connectionTopicId,
|
|
33065
|
+
operatorId,
|
|
33066
|
+
memo
|
|
33067
|
+
}) {
|
|
33068
|
+
const payload = {
|
|
33069
|
+
p: "hcs-10",
|
|
33070
|
+
op: "connection_created",
|
|
33071
|
+
connection_topic_id: connectionTopicId,
|
|
33072
|
+
outbound_topic_id: outboundTopicId,
|
|
33073
|
+
confirmed_request_id: confirmedRequestId,
|
|
33074
|
+
connection_request_id: connectionRequestId,
|
|
33075
|
+
operator_id: operatorId,
|
|
33076
|
+
m: memo
|
|
33077
|
+
};
|
|
33078
|
+
return await this.submitPayload(outboundTopicId, payload);
|
|
33079
|
+
}
|
|
33080
|
+
async getPublicKey(accountId) {
|
|
33081
|
+
return await this.mirrorNode.getPublicKey(accountId);
|
|
33082
|
+
}
|
|
33083
|
+
async handleConnectionRequest(inboundTopicId, requestingAccountId, connectionId, connectionMemo = "Connection accepted. Looking forward to collaborating!") {
|
|
33084
|
+
this.logger.info("Handling connection request");
|
|
33085
|
+
const userAccountId = this.hwc.getAccountInfo().accountId;
|
|
33086
|
+
if (!userAccountId) {
|
|
33087
|
+
throw new Error("Failed to retrieve user account ID");
|
|
33088
|
+
}
|
|
33089
|
+
const requesterKey = await this.mirrorNode.getPublicKey(
|
|
33090
|
+
requestingAccountId
|
|
33091
|
+
);
|
|
33092
|
+
const accountKey = await this.mirrorNode.getPublicKey(userAccountId);
|
|
33093
|
+
if (!accountKey) {
|
|
33094
|
+
throw new Error("Failed to retrieve public key");
|
|
33095
|
+
}
|
|
33096
|
+
const thresholdKey = new KeyList([accountKey, requesterKey], 1);
|
|
33097
|
+
const memo = `hcs-10:${inboundTopicId}:${connectionId}`;
|
|
33098
|
+
const transaction = new TopicCreateTransaction().setTopicMemo(memo).setAdminKey(thresholdKey).setSubmitKey(thresholdKey);
|
|
33099
|
+
this.logger.debug("Executing topic creation transaction");
|
|
33100
|
+
const receipt = await this.hwc.executeTransactionWithErrorHandling(
|
|
33101
|
+
transaction,
|
|
33102
|
+
false
|
|
33103
|
+
);
|
|
33104
|
+
if (receipt.error) {
|
|
33105
|
+
this.logger.error(receipt.error);
|
|
33106
|
+
throw new Error(receipt.error);
|
|
33107
|
+
}
|
|
33108
|
+
const result = receipt.result;
|
|
33109
|
+
if (!(result == null ? void 0 : result.topicId)) {
|
|
33110
|
+
this.logger.error("Failed to create topic: topicId is null");
|
|
33111
|
+
throw new Error("Failed to create topic: topicId is null");
|
|
33112
|
+
}
|
|
33113
|
+
const connectionTopicId = result.topicId.toString();
|
|
33114
|
+
const operatorId = `${inboundTopicId}@${userAccountId}`;
|
|
33115
|
+
const confirmedConnectionSequenceNumber = await this.confirmConnection(
|
|
33116
|
+
inboundTopicId,
|
|
33117
|
+
connectionTopicId,
|
|
33118
|
+
requestingAccountId,
|
|
33119
|
+
connectionId,
|
|
33120
|
+
operatorId,
|
|
33121
|
+
connectionMemo
|
|
33122
|
+
);
|
|
33123
|
+
return {
|
|
33124
|
+
connectionTopicId,
|
|
33125
|
+
confirmedConnectionSequenceNumber,
|
|
33126
|
+
operatorId
|
|
33127
|
+
};
|
|
33128
|
+
}
|
|
33129
|
+
async confirmConnection(inboundTopicId, connectionTopicId, connectedAccountId, connectionId, operatorId, memo) {
|
|
33130
|
+
var _a;
|
|
33131
|
+
this.logger.info("Confirming connection");
|
|
33132
|
+
const payload = {
|
|
33133
|
+
p: "hcs-10",
|
|
33134
|
+
op: "connection_created",
|
|
33135
|
+
connection_topic_id: connectionTopicId,
|
|
33136
|
+
connected_account_id: connectedAccountId,
|
|
33137
|
+
operator_id: operatorId,
|
|
33138
|
+
connection_id: connectionId,
|
|
33139
|
+
m: memo
|
|
33140
|
+
};
|
|
33141
|
+
const transactionResponse = await this.submitPayload(
|
|
33142
|
+
inboundTopicId,
|
|
33143
|
+
payload
|
|
33144
|
+
);
|
|
33145
|
+
if (!((_a = transactionResponse == null ? void 0 : transactionResponse.result) == null ? void 0 : _a.topicSequenceNumber)) {
|
|
33146
|
+
this.logger.error(
|
|
33147
|
+
"Failed to confirm connection: sequence number is null"
|
|
33148
|
+
);
|
|
33149
|
+
throw new Error("Failed to confirm connection: sequence number is null");
|
|
33150
|
+
}
|
|
33151
|
+
return transactionResponse.result.topicSequenceNumber.toNumber();
|
|
33152
|
+
}
|
|
33153
|
+
async submitMessage(topicId, content, metadata = {}, memo = "") {
|
|
33154
|
+
this.logger.info("Submitting message");
|
|
33155
|
+
const payload = {
|
|
33156
|
+
p: "hcs-10",
|
|
33157
|
+
op: "message",
|
|
33158
|
+
data: {
|
|
33159
|
+
content,
|
|
33160
|
+
metadata
|
|
33161
|
+
},
|
|
33162
|
+
m: memo
|
|
33163
|
+
};
|
|
33164
|
+
return await this.submitPayload(topicId, payload);
|
|
33165
|
+
}
|
|
33166
|
+
async createAgent(pfpBuffer, pfpFileName, agentName, agentDescription, capabilities, metadata) {
|
|
33167
|
+
try {
|
|
33168
|
+
const outboundTopicResult = await this.createTopic(
|
|
33169
|
+
"hcs-10:0:60:1",
|
|
33170
|
+
true,
|
|
33171
|
+
true
|
|
33172
|
+
);
|
|
33173
|
+
if (!outboundTopicResult.success || !outboundTopicResult.topicId) {
|
|
33174
|
+
return {
|
|
33175
|
+
outboundTopicId: "",
|
|
33176
|
+
inboundTopicId: "",
|
|
33177
|
+
pfpTopicId: "",
|
|
33178
|
+
profileTopicId: "",
|
|
33179
|
+
error: outboundTopicResult.error || "Failed to create outbound topic",
|
|
33180
|
+
success: false
|
|
33181
|
+
};
|
|
33182
|
+
}
|
|
33183
|
+
const inboundTopicResult = await this.createTopic(
|
|
33184
|
+
`hcs-10:0:60:0:${outboundTopicResult.topicId}`
|
|
33185
|
+
);
|
|
33186
|
+
if (!inboundTopicResult.success || !inboundTopicResult.topicId) {
|
|
33187
|
+
return {
|
|
33188
|
+
outboundTopicId: outboundTopicResult.topicId,
|
|
33189
|
+
inboundTopicId: "",
|
|
33190
|
+
pfpTopicId: "",
|
|
33191
|
+
profileTopicId: "",
|
|
33192
|
+
error: inboundTopicResult.error || "Failed to create inbound topic",
|
|
33193
|
+
success: false
|
|
33194
|
+
};
|
|
33195
|
+
}
|
|
33196
|
+
const pfpResult = await this.inscribePfp(pfpBuffer, pfpFileName);
|
|
33197
|
+
if (!pfpResult.success) {
|
|
33198
|
+
return {
|
|
33199
|
+
outboundTopicId: outboundTopicResult.topicId,
|
|
33200
|
+
inboundTopicId: inboundTopicResult.topicId,
|
|
33201
|
+
pfpTopicId: "",
|
|
33202
|
+
profileTopicId: "",
|
|
33203
|
+
error: pfpResult.error || "Failed to inscribe profile picture",
|
|
33204
|
+
success: false
|
|
33205
|
+
};
|
|
33206
|
+
}
|
|
33207
|
+
const profileResult = await this.storeHCS11Profile(
|
|
33208
|
+
agentName,
|
|
33209
|
+
agentDescription,
|
|
33210
|
+
inboundTopicResult.topicId,
|
|
33211
|
+
outboundTopicResult.topicId,
|
|
33212
|
+
capabilities,
|
|
33213
|
+
metadata,
|
|
33214
|
+
pfpBuffer,
|
|
33215
|
+
pfpFileName
|
|
33216
|
+
);
|
|
33217
|
+
if (!profileResult.success) {
|
|
33218
|
+
return {
|
|
33219
|
+
outboundTopicId: outboundTopicResult.topicId,
|
|
33220
|
+
inboundTopicId: inboundTopicResult.topicId,
|
|
33221
|
+
pfpTopicId: pfpResult.pfpTopicId,
|
|
33222
|
+
profileTopicId: "",
|
|
33223
|
+
error: profileResult.error || "Failed to store profile",
|
|
33224
|
+
success: false
|
|
33225
|
+
};
|
|
33226
|
+
}
|
|
33227
|
+
return {
|
|
33228
|
+
outboundTopicId: outboundTopicResult.topicId,
|
|
33229
|
+
inboundTopicId: inboundTopicResult.topicId,
|
|
33230
|
+
pfpTopicId: pfpResult.pfpTopicId,
|
|
33231
|
+
profileTopicId: profileResult.profileTopicId,
|
|
33232
|
+
success: true
|
|
33233
|
+
};
|
|
33234
|
+
} catch (error) {
|
|
33235
|
+
return {
|
|
33236
|
+
outboundTopicId: "",
|
|
33237
|
+
inboundTopicId: "",
|
|
33238
|
+
pfpTopicId: "",
|
|
33239
|
+
profileTopicId: "",
|
|
33240
|
+
error: error.message,
|
|
33241
|
+
success: false
|
|
33242
|
+
};
|
|
33243
|
+
}
|
|
33244
|
+
}
|
|
33245
|
+
async createAndRegisterAgent(name, description, capabilities, metadata, pfpBuffer, pfpFileName, network) {
|
|
33246
|
+
const { accountId } = this.getAccountAndSigner();
|
|
33247
|
+
const {
|
|
33248
|
+
outboundTopicId,
|
|
33249
|
+
inboundTopicId,
|
|
33250
|
+
pfpTopicId,
|
|
33251
|
+
profileTopicId,
|
|
33252
|
+
error,
|
|
33253
|
+
success
|
|
33254
|
+
} = await this.createAgent(
|
|
33255
|
+
pfpBuffer,
|
|
33256
|
+
pfpFileName,
|
|
33257
|
+
name,
|
|
33258
|
+
description,
|
|
33259
|
+
capabilities,
|
|
33260
|
+
metadata
|
|
33261
|
+
);
|
|
33262
|
+
if (!success || error) {
|
|
33263
|
+
throw new Error(error || "Failed to create agent");
|
|
33264
|
+
}
|
|
33265
|
+
const operatorId = `${inboundTopicId}@${accountId}`;
|
|
33266
|
+
await this.registerAgentWithGuardedRegistry(
|
|
33267
|
+
accountId,
|
|
33268
|
+
inboundTopicId,
|
|
33269
|
+
network
|
|
33270
|
+
);
|
|
33271
|
+
return {
|
|
33272
|
+
accountId,
|
|
33273
|
+
operatorId,
|
|
33274
|
+
inboundTopicId,
|
|
33275
|
+
outboundTopicId,
|
|
33276
|
+
profileTopicId,
|
|
33277
|
+
pfpTopicId,
|
|
33278
|
+
client: this
|
|
33279
|
+
};
|
|
33280
|
+
}
|
|
33281
|
+
async registerAgentWithGuardedRegistry(accountId, inboundTopicId, network = this.network, maxAttempts = 60, delayMs = 2e3) {
|
|
33282
|
+
try {
|
|
33283
|
+
this.logger.info("Registering agent with guarded registry");
|
|
33284
|
+
const registrationResult = await this.executeRegistration(
|
|
33285
|
+
accountId,
|
|
33286
|
+
inboundTopicId,
|
|
33287
|
+
network,
|
|
33288
|
+
this.guardedRegistryBaseUrl,
|
|
33289
|
+
this.logger
|
|
33290
|
+
);
|
|
33291
|
+
if (!registrationResult.success) {
|
|
33292
|
+
return registrationResult;
|
|
33293
|
+
}
|
|
33294
|
+
if (registrationResult.transaction) {
|
|
33295
|
+
const transaction = Transaction.fromBytes(
|
|
33296
|
+
Buffer2.from(registrationResult.transaction, "base64")
|
|
33297
|
+
);
|
|
33298
|
+
this.logger.info(`Processing registration transaction`);
|
|
33299
|
+
const txResult = await this.hwc.executeTransactionWithErrorHandling(
|
|
33300
|
+
transaction,
|
|
33301
|
+
false
|
|
33302
|
+
);
|
|
33303
|
+
if (txResult.error) {
|
|
33304
|
+
return {
|
|
33305
|
+
...registrationResult,
|
|
33306
|
+
error: txResult.error,
|
|
33307
|
+
success: false
|
|
33308
|
+
};
|
|
33309
|
+
}
|
|
33310
|
+
this.logger.info(`Successfully processed registration transaction`);
|
|
33311
|
+
}
|
|
33312
|
+
const confirmed = await this.waitForRegistrationConfirmation(
|
|
33313
|
+
registrationResult.transactionId,
|
|
33314
|
+
network,
|
|
33315
|
+
this.guardedRegistryBaseUrl,
|
|
33316
|
+
maxAttempts,
|
|
33317
|
+
delayMs
|
|
33318
|
+
);
|
|
33319
|
+
return {
|
|
33320
|
+
...registrationResult,
|
|
33321
|
+
confirmed
|
|
33322
|
+
};
|
|
33323
|
+
} catch (error) {
|
|
33324
|
+
return {
|
|
33325
|
+
error: `Error during registration: ${error.message}`,
|
|
33326
|
+
success: false
|
|
33327
|
+
};
|
|
33328
|
+
}
|
|
33329
|
+
}
|
|
33330
|
+
async storeHCS11Profile(agentName, agentDescription, inboundTopicId, outboundTopicId, capabilities = [], metadata = {}, pfpBuffer, pfpFileName) {
|
|
33331
|
+
try {
|
|
33332
|
+
let pfpTopicId;
|
|
33333
|
+
if (pfpBuffer && pfpFileName) {
|
|
33334
|
+
const pfpResult = await this.inscribePfp(pfpBuffer, pfpFileName);
|
|
33335
|
+
if (!pfpResult.success) {
|
|
33336
|
+
this.logger.error(
|
|
33337
|
+
"Failed to inscribe profile picture, continuing without PFP"
|
|
33338
|
+
);
|
|
33339
|
+
} else {
|
|
33340
|
+
pfpTopicId = pfpResult.pfpTopicId;
|
|
33341
|
+
}
|
|
33342
|
+
}
|
|
33343
|
+
const agentType = this.hcs11Client.getAgentTypeFromMetadata({
|
|
33344
|
+
type: metadata.type || "autonomous"
|
|
33345
|
+
});
|
|
33346
|
+
const formattedSocials = [];
|
|
33347
|
+
if (metadata.socials) {
|
|
33348
|
+
if (metadata.socials.twitter) {
|
|
33349
|
+
formattedSocials.push({
|
|
33350
|
+
platform: "twitter",
|
|
33351
|
+
handle: metadata.socials.twitter
|
|
33352
|
+
});
|
|
33353
|
+
}
|
|
33354
|
+
if (metadata.socials.discord) {
|
|
33355
|
+
formattedSocials.push({
|
|
33356
|
+
platform: "discord",
|
|
33357
|
+
handle: metadata.socials.discord
|
|
33358
|
+
});
|
|
33359
|
+
}
|
|
33360
|
+
if (metadata.socials.github) {
|
|
33361
|
+
formattedSocials.push({
|
|
33362
|
+
platform: "github",
|
|
33363
|
+
handle: metadata.socials.github
|
|
33364
|
+
});
|
|
33365
|
+
}
|
|
33366
|
+
if (metadata.socials.website) {
|
|
33367
|
+
formattedSocials.push({
|
|
33368
|
+
platform: "website",
|
|
33369
|
+
handle: metadata.socials.website
|
|
33370
|
+
});
|
|
33371
|
+
}
|
|
33372
|
+
if (metadata.socials.x) {
|
|
33373
|
+
formattedSocials.push({
|
|
33374
|
+
platform: "twitter",
|
|
33375
|
+
handle: metadata.socials.x
|
|
33376
|
+
});
|
|
33377
|
+
}
|
|
33378
|
+
if (metadata.socials.linkedin) {
|
|
33379
|
+
formattedSocials.push({
|
|
33380
|
+
platform: "linkedin",
|
|
33381
|
+
handle: metadata.socials.linkedin
|
|
33382
|
+
});
|
|
33383
|
+
}
|
|
33384
|
+
if (metadata.socials.youtube) {
|
|
33385
|
+
formattedSocials.push({
|
|
33386
|
+
platform: "youtube",
|
|
33387
|
+
handle: metadata.socials.youtube
|
|
33388
|
+
});
|
|
33389
|
+
}
|
|
33390
|
+
if (metadata.socials.telegram) {
|
|
33391
|
+
formattedSocials.push({
|
|
33392
|
+
platform: "telegram",
|
|
33393
|
+
handle: metadata.socials.telegram
|
|
33394
|
+
});
|
|
33395
|
+
}
|
|
33396
|
+
}
|
|
33397
|
+
const profile = this.hcs11Client.createAIAgentProfile(
|
|
33398
|
+
agentName,
|
|
33399
|
+
agentType,
|
|
33400
|
+
capabilities,
|
|
33401
|
+
metadata.model || "unknown",
|
|
33402
|
+
{
|
|
33403
|
+
alias: agentName.toLowerCase().replace(/\s+/g, "_"),
|
|
33404
|
+
bio: agentDescription,
|
|
33405
|
+
profileImage: pfpTopicId ? `hcs://1/${pfpTopicId}` : void 0,
|
|
33406
|
+
socials: formattedSocials.length > 0 ? formattedSocials : void 0,
|
|
33407
|
+
properties: {
|
|
33408
|
+
description: agentDescription,
|
|
33409
|
+
version: metadata.version || "1.0.0",
|
|
33410
|
+
creator: metadata.creator || "Unknown",
|
|
33411
|
+
supported_languages: metadata.supported_languages || ["en"],
|
|
33412
|
+
permissions: metadata.permissions || [],
|
|
33413
|
+
model_details: metadata.model_details,
|
|
33414
|
+
training: metadata.training,
|
|
33415
|
+
capabilities_description: metadata.capabilities_description,
|
|
33416
|
+
...metadata
|
|
33417
|
+
},
|
|
33418
|
+
inboundTopicId,
|
|
33419
|
+
outboundTopicId,
|
|
33420
|
+
creator: metadata.creator
|
|
33421
|
+
}
|
|
33422
|
+
);
|
|
33423
|
+
const profileResult = await this.hcs11Client.createAndInscribeProfile(
|
|
33424
|
+
profile,
|
|
33425
|
+
true
|
|
33426
|
+
);
|
|
33427
|
+
if (!profileResult.success) {
|
|
33428
|
+
return {
|
|
33429
|
+
profileTopicId: "",
|
|
33430
|
+
success: false,
|
|
33431
|
+
error: profileResult.error || "Failed to inscribe profile"
|
|
33432
|
+
};
|
|
33433
|
+
}
|
|
33434
|
+
return {
|
|
33435
|
+
profileTopicId: profileResult.profileTopicId,
|
|
33436
|
+
pfpTopicId,
|
|
33437
|
+
success: true
|
|
33438
|
+
};
|
|
33439
|
+
} catch (error) {
|
|
33440
|
+
return {
|
|
33441
|
+
profileTopicId: "",
|
|
33442
|
+
success: false,
|
|
33443
|
+
error: error.message
|
|
33444
|
+
};
|
|
33445
|
+
}
|
|
33446
|
+
}
|
|
33447
|
+
async createTopic(memo, adminKey, submitKey) {
|
|
33448
|
+
this.logger.info("Creating topic");
|
|
33449
|
+
const { accountId, signer } = this.getAccountAndSigner();
|
|
33450
|
+
const transaction = new TopicCreateTransaction().setTopicMemo(memo);
|
|
33451
|
+
const publicKey = await this.mirrorNode.getPublicKey(accountId);
|
|
33452
|
+
if (adminKey && publicKey) {
|
|
33453
|
+
transaction.setAdminKey(publicKey);
|
|
33454
|
+
transaction.setAutoRenewAccountId(accountId);
|
|
33455
|
+
}
|
|
33456
|
+
if (submitKey && publicKey) {
|
|
33457
|
+
transaction.setSubmitKey(publicKey);
|
|
33458
|
+
}
|
|
33459
|
+
const transactionResponse = await this.hwc.executeTransactionWithErrorHandling(
|
|
33460
|
+
transaction,
|
|
33461
|
+
false
|
|
33462
|
+
);
|
|
33463
|
+
const error = transactionResponse.error;
|
|
33464
|
+
if (error) {
|
|
33465
|
+
this.logger.error(error);
|
|
33466
|
+
return {
|
|
33467
|
+
success: false,
|
|
33468
|
+
error
|
|
33469
|
+
};
|
|
33470
|
+
}
|
|
33471
|
+
const result = transactionResponse.result;
|
|
33472
|
+
if (!(result == null ? void 0 : result.topicId)) {
|
|
33473
|
+
this.logger.error("Failed to create topic: topicId is null");
|
|
33474
|
+
return {
|
|
33475
|
+
success: false,
|
|
33476
|
+
error: "Failed to create topic: topicId is null"
|
|
33477
|
+
};
|
|
33478
|
+
}
|
|
33479
|
+
return {
|
|
33480
|
+
success: true,
|
|
33481
|
+
topicId: result.topicId.toString()
|
|
33482
|
+
};
|
|
33483
|
+
}
|
|
33484
|
+
async submitPayload(topicId, payload) {
|
|
33485
|
+
this.logger.debug("Submitting payload");
|
|
33486
|
+
const transaction = new TopicMessageSubmitTransaction().setTopicId(topicId).setMessage(JSON.stringify(payload));
|
|
33487
|
+
return await this.hwc.executeTransactionWithErrorHandling(
|
|
33488
|
+
// @ts-ignore
|
|
33489
|
+
transaction,
|
|
33490
|
+
false
|
|
33491
|
+
);
|
|
33492
|
+
}
|
|
33493
|
+
async inscribeFile(buffer2, fileName) {
|
|
33494
|
+
const { accountId, signer } = this.getAccountAndSigner();
|
|
33495
|
+
const mimeType = mimeTypes.lookup(fileName) || "application/octet-stream";
|
|
33496
|
+
const sdk = await InscriptionSDK.createWithAuth({
|
|
33497
|
+
type: "client",
|
|
33498
|
+
accountId,
|
|
33499
|
+
signer,
|
|
33500
|
+
network: this.network
|
|
33501
|
+
});
|
|
33502
|
+
const result = await sdk.inscribe(
|
|
33503
|
+
{
|
|
33504
|
+
file: {
|
|
33505
|
+
type: "base64",
|
|
33506
|
+
base64: buffer2.toString("base64"),
|
|
33507
|
+
fileName,
|
|
33508
|
+
mimeType
|
|
33509
|
+
},
|
|
33510
|
+
holderId: accountId.toString(),
|
|
33511
|
+
mode: "file",
|
|
33512
|
+
network: this.network
|
|
33513
|
+
},
|
|
33514
|
+
signer
|
|
33515
|
+
);
|
|
33516
|
+
if (!result.transactionId || !result.jobId) {
|
|
33517
|
+
this.logger.error("Failed to inscribe, no transaction ID or job ID.");
|
|
33518
|
+
throw new Error("Failed to inscribe, no transaction ID or job ID.");
|
|
33519
|
+
}
|
|
33520
|
+
if (result.transactionId && result.jobId) {
|
|
33521
|
+
this.logger.info(
|
|
33522
|
+
`Transaction ID: ${result.transactionId}, Job ID: ${result.jobId}`
|
|
33523
|
+
);
|
|
33524
|
+
}
|
|
33525
|
+
const status = await sdk.waitForInscription(result.jobId, 30, 4e3, true);
|
|
33526
|
+
return status;
|
|
33527
|
+
}
|
|
33528
|
+
getAccountAndSigner() {
|
|
33529
|
+
const accountInfo = this.hwc.getAccountInfo();
|
|
33530
|
+
const accountId = accountInfo.accountId.toString();
|
|
33531
|
+
const signer = this.hwc.dAppConnector.signers.find((s) => {
|
|
33532
|
+
return s.getAccountId().toString() === accountId;
|
|
33533
|
+
});
|
|
33534
|
+
if (!signer) {
|
|
33535
|
+
this.logger.error("Failed to find signer");
|
|
33536
|
+
throw new Error("Failed to find signer");
|
|
33537
|
+
}
|
|
33538
|
+
return { accountId, signer };
|
|
33539
|
+
}
|
|
33540
|
+
/**
|
|
33541
|
+
* Inscribes a profile picture file to the Hedera network
|
|
33542
|
+
* @param buffer File buffer to inscribe
|
|
33543
|
+
* @param fileName Filename for the inscription
|
|
33544
|
+
* @returns Object containing the topic ID and success status
|
|
33545
|
+
*/
|
|
33546
|
+
async inscribePfp(buffer2, fileName) {
|
|
33547
|
+
try {
|
|
33548
|
+
this.logger.info("Inscribing profile picture using HCS-11 client");
|
|
33549
|
+
const imageResult = await this.hcs11Client.inscribeImage(
|
|
33550
|
+
buffer2,
|
|
33551
|
+
fileName
|
|
33552
|
+
);
|
|
33553
|
+
if (!imageResult.success) {
|
|
33554
|
+
this.logger.error(
|
|
33555
|
+
`Failed to inscribe profile picture: ${imageResult.error}`
|
|
33556
|
+
);
|
|
33557
|
+
return {
|
|
33558
|
+
pfpTopicId: "",
|
|
33559
|
+
success: false,
|
|
33560
|
+
error: imageResult.error || "Failed to inscribe profile picture"
|
|
33561
|
+
};
|
|
33562
|
+
}
|
|
33563
|
+
this.logger.info(
|
|
33564
|
+
`Successfully inscribed profile picture with topic ID: ${imageResult.imageTopicId}`
|
|
33565
|
+
);
|
|
33566
|
+
return {
|
|
33567
|
+
pfpTopicId: imageResult.imageTopicId,
|
|
33568
|
+
success: true
|
|
33569
|
+
};
|
|
33570
|
+
} catch (error) {
|
|
33571
|
+
this.logger.error(`Error inscribing profile picture: ${error.message}`);
|
|
33572
|
+
return {
|
|
33573
|
+
pfpTopicId: "",
|
|
33574
|
+
success: false,
|
|
33575
|
+
error: error.message
|
|
33576
|
+
};
|
|
33577
|
+
}
|
|
33578
|
+
}
|
|
33579
|
+
}
|
|
32859
33580
|
export {
|
|
32860
33581
|
AIAgentCapability,
|
|
32861
33582
|
AIAgentType,
|
|
32862
33583
|
AccountCreationError,
|
|
32863
33584
|
AgentBuilder,
|
|
33585
|
+
BrowserHCSClient,
|
|
32864
33586
|
ConnectionConfirmationError,
|
|
32865
33587
|
EVMBridge,
|
|
32866
33588
|
EndpointType,
|
|
33589
|
+
FeeConfigBuilder,
|
|
32867
33590
|
HCS,
|
|
32868
33591
|
HCS10BaseClient,
|
|
32869
33592
|
HCS10Cache,
|