@hashgraphonline/standards-sdk 0.0.18 → 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.
@@ -3,3 +3,4 @@ export * from './errors';
3
3
  export * from './agent-builder';
4
4
  export * from './base-client';
5
5
  export * from './registrations';
6
+ export * from './browser';
@@ -32982,11 +32982,607 @@ class AgentBuilder {
32982
32982
  return this.config;
32983
32983
  }
32984
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
+ }
32985
33580
  export {
32986
33581
  AIAgentCapability,
32987
33582
  AIAgentType,
32988
33583
  AccountCreationError,
32989
33584
  AgentBuilder,
33585
+ BrowserHCSClient,
32990
33586
  ConnectionConfirmationError,
32991
33587
  EVMBridge,
32992
33588
  EndpointType,