@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.
@@ -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 proto = { foo: function() {
6227
+ const proto2 = { foo: function() {
6227
6228
  return 42;
6228
6229
  } };
6229
- Object.setPrototypeOf(proto, GlobalUint8Array.prototype);
6230
- Object.setPrototypeOf(arr, proto);
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 proto = { foo: function() {
8021
+ const proto2 = { foo: function() {
8021
8022
  return 42;
8022
8023
  } };
8023
- Object.setPrototypeOf(proto, GlobalUint8Array.prototype);
8024
- Object.setPrototypeOf(arr, proto);
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 accountInfoUrl = `${this.baseUrl}/api/v1/accounts/${accountId}`;
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 response = await axios.get(
15518
- `${this.baseUrl}/api/v1/accounts/${accountId}`
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 getAccountInfo(accountId) {
15611
+ async checkKeyListAccess(keyBytes, userPublicKey) {
15615
15612
  try {
15616
- const accountInfoUrl = `${this.baseUrl}/api/v1/accounts/${accountId}`;
15617
- const response = await axios.get(accountInfoUrl);
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
- throw new Error(
15626
- `Failed to retrieve account information: ${error.message}`
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.retrieveOutboundConnectTopicFromNetwork(
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.retrieveOutboundConnectTopicFromNetwork(
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 additionalExemptAccounts = [requestingAccountId];
32338
+ const feeConfig = connectionFeeConfig.build();
32206
32339
  const modifiedFeeConfig = {
32207
- ...connectionFeeConfig,
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.retrieveOutboundConnectTopicFromNetwork(
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
- this.logger.info(
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
- const hasSubmitKey = topicInfo.submit_key && topicInfo.submit_key.key;
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
- const topicSubmitKey = PublicKey.fromString(topicInfo.submit_key.key);
32561
- if (userPublicKey.toString() === topicSubmitKey.toString()) {
32562
- return { canSubmit: true, requiresFee: false };
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(`Error comparing keys: ${error}`);
32700
+ this.logger.error(
32701
+ `Key validation error: ${error instanceof Error ? error.message : String(error)}`
32702
+ );
32566
32703
  }
32567
- const hasFeeScheduleKey = topicInfo.fee_schedule_key && topicInfo.fee_schedule_key.key;
32568
- if (hasFeeScheduleKey && topicInfo.custom_fees) {
32569
- const customFees = topicInfo.custom_fees;
32570
- if (customFees && customFees.fixed_fees && customFees.fixed_fees.length > 0) {
32571
- return {
32572
- canSubmit: true,
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
- this.logger.error(`Error validating topic submission: ${error.message}`);
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: ${error.message}`
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(feeAmount, feeCollectorAccountId, exemptAccounts) {
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(feeAmount, feeCollectorAccountId, exemptAccounts) {
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,