@hashgraphonline/standards-sdk 0.0.83 → 0.0.85

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.
Files changed (239) hide show
  1. package/dist/es/hcs-10/base-client.d.ts.map +1 -1
  2. package/dist/es/hcs-10/connections-manager.d.ts +203 -0
  3. package/dist/es/hcs-10/connections-manager.d.ts.map +1 -0
  4. package/dist/es/hcs-10/index.d.ts +1 -0
  5. package/dist/es/hcs-10/index.d.ts.map +1 -1
  6. package/dist/es/standards-sdk.es.js +13 -11
  7. package/dist/es/standards-sdk.es.js.map +1 -1
  8. package/dist/es/standards-sdk.es10.js +778 -115
  9. package/dist/es/standards-sdk.es10.js.map +1 -1
  10. package/dist/es/standards-sdk.es100.js +127 -138
  11. package/dist/es/standards-sdk.es100.js.map +1 -1
  12. package/dist/es/standards-sdk.es101.js +90 -22
  13. package/dist/es/standards-sdk.es101.js.map +1 -1
  14. package/dist/es/standards-sdk.es102.js +78 -787
  15. package/dist/es/standards-sdk.es102.js.map +1 -1
  16. package/dist/es/standards-sdk.es103.js +31 -3
  17. package/dist/es/standards-sdk.es103.js.map +1 -1
  18. package/dist/es/standards-sdk.es104.js +5 -142
  19. package/dist/es/standards-sdk.es104.js.map +1 -1
  20. package/dist/es/standards-sdk.es105.js +145 -160
  21. package/dist/es/standards-sdk.es105.js.map +1 -1
  22. package/dist/es/standards-sdk.es106.js +22 -33
  23. package/dist/es/standards-sdk.es106.js.map +1 -1
  24. package/dist/es/standards-sdk.es107.js +790 -30
  25. package/dist/es/standards-sdk.es107.js.map +1 -1
  26. package/dist/es/standards-sdk.es108.js +174 -9
  27. package/dist/es/standards-sdk.es108.js.map +1 -1
  28. package/dist/es/standards-sdk.es109.js +139 -30
  29. package/dist/es/standards-sdk.es109.js.map +1 -1
  30. package/dist/es/standards-sdk.es11.js +103 -58
  31. package/dist/es/standards-sdk.es11.js.map +1 -1
  32. package/dist/es/standards-sdk.es110.js +16 -414
  33. package/dist/es/standards-sdk.es110.js.map +1 -1
  34. package/dist/es/standards-sdk.es111.js +27 -2
  35. package/dist/es/standards-sdk.es111.js.map +1 -1
  36. package/dist/es/standards-sdk.es112.js +24 -118
  37. package/dist/es/standards-sdk.es112.js.map +1 -1
  38. package/dist/es/standards-sdk.es113.js +36 -19
  39. package/dist/es/standards-sdk.es113.js.map +1 -1
  40. package/dist/es/standards-sdk.es114.js +3 -26
  41. package/dist/es/standards-sdk.es114.js.map +1 -1
  42. package/dist/es/standards-sdk.es115.js +418 -25
  43. package/dist/es/standards-sdk.es115.js.map +1 -1
  44. package/dist/es/standards-sdk.es116.js +2 -38
  45. package/dist/es/standards-sdk.es116.js.map +1 -1
  46. package/dist/es/standards-sdk.es117.js +123 -0
  47. package/dist/es/standards-sdk.es117.js.map +1 -0
  48. package/dist/es/standards-sdk.es12.js +82 -628
  49. package/dist/es/standards-sdk.es12.js.map +1 -1
  50. package/dist/es/standards-sdk.es13.js +650 -85
  51. package/dist/es/standards-sdk.es13.js.map +1 -1
  52. package/dist/es/standards-sdk.es14.js +84 -58
  53. package/dist/es/standards-sdk.es14.js.map +1 -1
  54. package/dist/es/standards-sdk.es15.js +57 -20
  55. package/dist/es/standards-sdk.es15.js.map +1 -1
  56. package/dist/es/standards-sdk.es16.js +18 -156
  57. package/dist/es/standards-sdk.es16.js.map +1 -1
  58. package/dist/es/standards-sdk.es17.js +138 -385
  59. package/dist/es/standards-sdk.es17.js.map +1 -1
  60. package/dist/es/standards-sdk.es18.js +385 -315
  61. package/dist/es/standards-sdk.es18.js.map +1 -1
  62. package/dist/es/standards-sdk.es19.js +310 -128
  63. package/dist/es/standards-sdk.es19.js.map +1 -1
  64. package/dist/es/standards-sdk.es2.js +1 -12
  65. package/dist/es/standards-sdk.es2.js.map +1 -1
  66. package/dist/es/standards-sdk.es20.js +155 -7
  67. package/dist/es/standards-sdk.es20.js.map +1 -1
  68. package/dist/es/standards-sdk.es21.js +7 -1767
  69. package/dist/es/standards-sdk.es21.js.map +1 -1
  70. package/dist/es/standards-sdk.es22.js +1767 -36
  71. package/dist/es/standards-sdk.es22.js.map +1 -1
  72. package/dist/es/standards-sdk.es23.js +36 -48
  73. package/dist/es/standards-sdk.es23.js.map +1 -1
  74. package/dist/es/standards-sdk.es24.js +21 -7163
  75. package/dist/es/standards-sdk.es24.js.map +1 -1
  76. package/dist/es/standards-sdk.es25.js +7190 -3
  77. package/dist/es/standards-sdk.es25.js.map +1 -1
  78. package/dist/es/standards-sdk.es26.js +3 -2
  79. package/dist/es/standards-sdk.es26.js.map +1 -1
  80. package/dist/es/standards-sdk.es27.js +2 -4167
  81. package/dist/es/standards-sdk.es27.js.map +1 -1
  82. package/dist/es/standards-sdk.es28.js +10 -10
  83. package/dist/es/standards-sdk.es29.js +4167 -5
  84. package/dist/es/standards-sdk.es29.js.map +1 -1
  85. package/dist/es/standards-sdk.es3.js +1 -1
  86. package/dist/es/standards-sdk.es30.js +5 -101
  87. package/dist/es/standards-sdk.es30.js.map +1 -1
  88. package/dist/es/standards-sdk.es31.js +364 -2
  89. package/dist/es/standards-sdk.es31.js.map +1 -1
  90. package/dist/es/standards-sdk.es32.js +5 -15
  91. package/dist/es/standards-sdk.es32.js.map +1 -1
  92. package/dist/es/standards-sdk.es33.js +167 -397
  93. package/dist/es/standards-sdk.es33.js.map +1 -1
  94. package/dist/es/standards-sdk.es34.js +68 -351
  95. package/dist/es/standards-sdk.es34.js.map +1 -1
  96. package/dist/es/standards-sdk.es35.js +113 -5
  97. package/dist/es/standards-sdk.es35.js.map +1 -1
  98. package/dist/es/standards-sdk.es36.js +43 -170
  99. package/dist/es/standards-sdk.es36.js.map +1 -1
  100. package/dist/es/standards-sdk.es37.js +9 -80
  101. package/dist/es/standards-sdk.es37.js.map +1 -1
  102. package/dist/es/standards-sdk.es38.js +87 -104
  103. package/dist/es/standards-sdk.es38.js.map +1 -1
  104. package/dist/es/standards-sdk.es39.js +3 -51
  105. package/dist/es/standards-sdk.es39.js.map +1 -1
  106. package/dist/es/standards-sdk.es4.js +1 -1
  107. package/dist/es/standards-sdk.es40.js +2 -10
  108. package/dist/es/standards-sdk.es40.js.map +1 -1
  109. package/dist/es/standards-sdk.es41.js +102 -86
  110. package/dist/es/standards-sdk.es41.js.map +1 -1
  111. package/dist/es/standards-sdk.es42.js +73 -3
  112. package/dist/es/standards-sdk.es42.js.map +1 -1
  113. package/dist/es/standards-sdk.es43.js +6 -2
  114. package/dist/es/standards-sdk.es43.js.map +1 -1
  115. package/dist/es/standards-sdk.es44.js +4 -112
  116. package/dist/es/standards-sdk.es44.js.map +1 -1
  117. package/dist/es/standards-sdk.es45.js +216 -69
  118. package/dist/es/standards-sdk.es45.js.map +1 -1
  119. package/dist/es/standards-sdk.es46.js +58 -6
  120. package/dist/es/standards-sdk.es46.js.map +1 -1
  121. package/dist/es/standards-sdk.es47.js +69 -5
  122. package/dist/es/standards-sdk.es47.js.map +1 -1
  123. package/dist/es/standards-sdk.es48.js +3 -221
  124. package/dist/es/standards-sdk.es48.js.map +1 -1
  125. package/dist/es/standards-sdk.es49.js +158 -52
  126. package/dist/es/standards-sdk.es49.js.map +1 -1
  127. package/dist/es/standards-sdk.es5.js +6 -8
  128. package/dist/es/standards-sdk.es5.js.map +1 -1
  129. package/dist/es/standards-sdk.es50.js +32 -69
  130. package/dist/es/standards-sdk.es50.js.map +1 -1
  131. package/dist/es/standards-sdk.es51.js +63 -2282
  132. package/dist/es/standards-sdk.es51.js.map +1 -1
  133. package/dist/es/standards-sdk.es52.js +47 -161
  134. package/dist/es/standards-sdk.es52.js.map +1 -1
  135. package/dist/es/standards-sdk.es53.js +8 -7134
  136. package/dist/es/standards-sdk.es53.js.map +1 -1
  137. package/dist/es/standards-sdk.es54.js +65 -3
  138. package/dist/es/standards-sdk.es54.js.map +1 -1
  139. package/dist/es/standards-sdk.es55.js +6 -32
  140. package/dist/es/standards-sdk.es55.js.map +1 -1
  141. package/dist/es/standards-sdk.es56.js +13 -61
  142. package/dist/es/standards-sdk.es56.js.map +1 -1
  143. package/dist/es/standards-sdk.es57.js +7 -50
  144. package/dist/es/standards-sdk.es57.js.map +1 -1
  145. package/dist/es/standards-sdk.es58.js +45 -10
  146. package/dist/es/standards-sdk.es58.js.map +1 -1
  147. package/dist/es/standards-sdk.es59.js +2 -65
  148. package/dist/es/standards-sdk.es59.js.map +1 -1
  149. package/dist/es/standards-sdk.es60.js +135 -5
  150. package/dist/es/standards-sdk.es60.js.map +1 -1
  151. package/dist/es/standards-sdk.es61.js +170 -13
  152. package/dist/es/standards-sdk.es61.js.map +1 -1
  153. package/dist/es/standards-sdk.es62.js +101 -7
  154. package/dist/es/standards-sdk.es62.js.map +1 -1
  155. package/dist/es/standards-sdk.es63.js +2 -45
  156. package/dist/es/standards-sdk.es63.js.map +1 -1
  157. package/dist/es/standards-sdk.es64.js +16 -2
  158. package/dist/es/standards-sdk.es64.js.map +1 -1
  159. package/dist/es/standards-sdk.es65.js +404 -131
  160. package/dist/es/standards-sdk.es65.js.map +1 -1
  161. package/dist/es/standards-sdk.es66.js +12 -171
  162. package/dist/es/standards-sdk.es66.js.map +1 -1
  163. package/dist/es/standards-sdk.es67.js +13 -13
  164. package/dist/es/standards-sdk.es67.js.map +1 -1
  165. package/dist/es/standards-sdk.es68.js +32 -13
  166. package/dist/es/standards-sdk.es68.js.map +1 -1
  167. package/dist/es/standards-sdk.es69.js +15 -2
  168. package/dist/es/standards-sdk.es69.js.map +1 -1
  169. package/dist/es/standards-sdk.es7.js +8 -8
  170. package/dist/es/standards-sdk.es70.js +3 -31
  171. package/dist/es/standards-sdk.es70.js.map +1 -1
  172. package/dist/es/standards-sdk.es71.js +3 -14
  173. package/dist/es/standards-sdk.es71.js.map +1 -1
  174. package/dist/es/standards-sdk.es72.js +15 -3
  175. package/dist/es/standards-sdk.es72.js.map +1 -1
  176. package/dist/es/standards-sdk.es73.js +4 -3
  177. package/dist/es/standards-sdk.es73.js.map +1 -1
  178. package/dist/es/standards-sdk.es74.js +39 -16
  179. package/dist/es/standards-sdk.es74.js.map +1 -1
  180. package/dist/es/standards-sdk.es75.js +40 -5
  181. package/dist/es/standards-sdk.es75.js.map +1 -1
  182. package/dist/es/standards-sdk.es76.js +35 -37
  183. package/dist/es/standards-sdk.es76.js.map +1 -1
  184. package/dist/es/standards-sdk.es77.js +72 -34
  185. package/dist/es/standards-sdk.es77.js.map +1 -1
  186. package/dist/es/standards-sdk.es78.js +2281 -36
  187. package/dist/es/standards-sdk.es78.js.map +1 -1
  188. package/dist/es/standards-sdk.es79.js +2 -78
  189. package/dist/es/standards-sdk.es79.js.map +1 -1
  190. package/dist/es/standards-sdk.es8.js +8 -8
  191. package/dist/es/standards-sdk.es80.js +7136 -3
  192. package/dist/es/standards-sdk.es80.js.map +1 -1
  193. package/dist/es/standards-sdk.es81.js +3 -2
  194. package/dist/es/standards-sdk.es81.js.map +1 -1
  195. package/dist/es/standards-sdk.es82.js +2 -2
  196. package/dist/es/standards-sdk.es82.js.map +1 -1
  197. package/dist/es/standards-sdk.es83.js +2 -195
  198. package/dist/es/standards-sdk.es83.js.map +1 -1
  199. package/dist/es/standards-sdk.es84.js +31 -435
  200. package/dist/es/standards-sdk.es84.js.map +1 -1
  201. package/dist/es/standards-sdk.es85.js +31 -23
  202. package/dist/es/standards-sdk.es85.js.map +1 -1
  203. package/dist/es/standards-sdk.es86.js +9 -139
  204. package/dist/es/standards-sdk.es86.js.map +1 -1
  205. package/dist/es/standards-sdk.es87.js +32 -16
  206. package/dist/es/standards-sdk.es87.js.map +1 -1
  207. package/dist/es/standards-sdk.es88.js +189 -23
  208. package/dist/es/standards-sdk.es88.js.map +1 -1
  209. package/dist/es/standards-sdk.es89.js +433 -24
  210. package/dist/es/standards-sdk.es89.js.map +1 -1
  211. package/dist/es/standards-sdk.es9.js +2 -2
  212. package/dist/es/standards-sdk.es90.js +16 -12
  213. package/dist/es/standards-sdk.es90.js.map +1 -1
  214. package/dist/es/standards-sdk.es91.js +126 -31
  215. package/dist/es/standards-sdk.es91.js.map +1 -1
  216. package/dist/es/standards-sdk.es92.js +9 -9
  217. package/dist/es/standards-sdk.es92.js.map +1 -1
  218. package/dist/es/standards-sdk.es93.js +22 -54
  219. package/dist/es/standards-sdk.es93.js.map +1 -1
  220. package/dist/es/standards-sdk.es94.js +20 -1280
  221. package/dist/es/standards-sdk.es94.js.map +1 -1
  222. package/dist/es/standards-sdk.es95.js +17 -144
  223. package/dist/es/standards-sdk.es95.js.map +1 -1
  224. package/dist/es/standards-sdk.es96.js +39 -86
  225. package/dist/es/standards-sdk.es96.js.map +1 -1
  226. package/dist/es/standards-sdk.es97.js +13 -79
  227. package/dist/es/standards-sdk.es97.js.map +1 -1
  228. package/dist/es/standards-sdk.es98.js +57 -28
  229. package/dist/es/standards-sdk.es98.js.map +1 -1
  230. package/dist/es/standards-sdk.es99.js +1288 -5
  231. package/dist/es/standards-sdk.es99.js.map +1 -1
  232. package/dist/umd/hcs-10/base-client.d.ts.map +1 -1
  233. package/dist/umd/hcs-10/connections-manager.d.ts +203 -0
  234. package/dist/umd/hcs-10/connections-manager.d.ts.map +1 -0
  235. package/dist/umd/hcs-10/index.d.ts +1 -0
  236. package/dist/umd/hcs-10/index.d.ts.map +1 -1
  237. package/dist/umd/standards-sdk.umd.js +9 -9
  238. package/dist/umd/standards-sdk.umd.js.map +1 -1
  239. package/package.json +10 -4
@@ -1 +1 @@
1
- {"version":3,"file":"standards-sdk.es19.js","sources":["../../src/fees/fee-config-builder.ts"],"sourcesContent":["import {\n FeeConfigBuilderInterface,\n TokenFeeConfig,\n TopicFeeConfig,\n CustomFeeType,\n} from './types';\nimport { HederaMirrorNode } from '../services/mirror-node';\nimport { Logger } from '../utils/logger';\nimport { NetworkType } from '../utils/types';\n\n/**\n * FeeConfigBuilder provides a fluent interface for creating fee configurations\n * for HCS-10 topics. This makes it easy to configure fees without dealing with\n * the complexity of the underlying fee structure.\n *\n * Example usage:\n *\n * // Super simple one-liner with the factory method\n * const simpleFeeConfig = FeeConfigBuilder.forHbar(5, '0.0.12345', NetworkType.TESTNET, new Logger(), ['0.0.67890']);\n *\n * // With multiple fees:\n * const multipleFeeConfig = new FeeConfigBuilder({\n * network: NetworkType.TESTNET,\n * logger: new Logger(),\n * defaultCollectorAccountId: '0.0.12345',\n * defaultExemptAccountIds: ['0.0.67890']\n * })\n * .withHbarFee(1) // 1 HBAR fee\n * .withTokenFee(10, '0.0.54321') // 10 units of token 0.0.54321\n * .build();\n *\n * With Agent Builder\n * const agent = new AgentBuilder()\n * .setName('Fee Collector Agent')\n * .setDescription('An agent that collects fees')\n * .setInboundTopicType(InboundTopicType.FEE_BASED)\n * .setFeeConfig(FeeConfigBuilder.forHbar(1, '0.0.12345', NetworkType.TESTNET, new Logger(), ['0.0.67890']))\n * .setNetwork('testnet')\n .build();\n\n * Directly with client\n * const client = new HCS10Client(config);\n * const connectionFeeConfig = new FeeConfigBuilder({\n * network: NetworkType.TESTNET,\n * logger: new Logger(),\n * defaultCollectorAccountId: client.getAccountAndSigner().accountId,\n * defaultExemptAccountIds: ['0.0.67890']\n * })\n * .withHbarFee(0.5) // 0.5 HBAR (simple!)\n * .build();\n\n * const result = await client.handleConnectionRequest(\n * inboundTopicId,\n * requestingAccountId,\n * connectionRequestId,\n * connectionFeeConfig\n * );\n*/\nexport interface FeeConfigBuilderOptions {\n network: NetworkType;\n logger: Logger;\n defaultCollectorAccountId?: string;\n}\n\nexport class FeeConfigBuilder implements FeeConfigBuilderInterface {\n private customFees: TokenFeeConfig[] = [];\n private mirrorNode: HederaMirrorNode;\n private logger: Logger;\n private defaultCollectorAccountId: string;\n\n constructor(options: FeeConfigBuilderOptions) {\n this.logger = options.logger;\n this.mirrorNode = new HederaMirrorNode(options.network, options.logger);\n this.defaultCollectorAccountId = options.defaultCollectorAccountId || '';\n }\n\n /**\n * Static factory method to create a FeeConfigBuilder with a single HBAR fee.\n * @param hbarAmount Amount in HBAR.\n * @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.\n * @param network Network type ('mainnet' or 'testnet').\n * @param logger Logger instance.\n * @param exemptAccounts Optional array of account IDs exempt from this fee.\n * @returns A configured FeeConfigBuilder instance.\n */\n static forHbar(\n hbarAmount: number,\n collectorAccountId: string | undefined,\n network: NetworkType,\n logger: Logger,\n exemptAccounts: string[] = []\n ): FeeConfigBuilder {\n const builder = new FeeConfigBuilder({\n network,\n logger,\n defaultCollectorAccountId: collectorAccountId,\n });\n return builder.addHbarFee(hbarAmount, collectorAccountId, exemptAccounts);\n }\n\n /**\n * Static factory method to create a FeeConfigBuilder with a single token fee.\n * Automatically fetches token decimals if not provided.\n * @param tokenAmount Amount of tokens.\n * @param feeTokenId Token ID for the fee.\n * @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.\n * @param network Network type ('mainnet' or 'testnet').\n * @param logger Logger instance.\n * @param exemptAccounts Optional array of account IDs exempt from this fee.\n * @param decimals Optional decimals for the token (fetched if omitted).\n * @returns A Promise resolving to a configured FeeConfigBuilder instance.\n */\n static async forToken(\n tokenAmount: number,\n feeTokenId: string,\n collectorAccountId: string | undefined,\n network: NetworkType,\n logger: Logger,\n exemptAccounts: string[] = [],\n decimals?: number\n ): Promise<FeeConfigBuilder> {\n const builder = new FeeConfigBuilder({\n network,\n logger,\n defaultCollectorAccountId: collectorAccountId,\n });\n await builder.addTokenFee(\n tokenAmount,\n feeTokenId,\n collectorAccountId,\n decimals,\n exemptAccounts\n );\n return builder;\n }\n\n /**\n * Adds an HBAR fee configuration to the builder.\n * Allows chaining multiple fee additions.\n * @param hbarAmount The amount in HBAR (e.g., 0.5).\n * @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.\n * @param exemptAccountIds Optional. Accounts specifically exempt from *this* HBAR fee.\n * @returns This FeeConfigBuilder instance for chaining.\n */\n addHbarFee(\n hbarAmount: number,\n collectorAccountId?: string,\n exemptAccountIds: string[] = []\n ): FeeConfigBuilder {\n if (hbarAmount <= 0) {\n throw new Error('HBAR amount must be greater than zero');\n }\n\n this.customFees.push({\n feeAmount: {\n amount: hbarAmount * 100_000_000,\n decimals: 0,\n },\n feeCollectorAccountId: collectorAccountId || '',\n feeTokenId: undefined,\n exemptAccounts: [...exemptAccountIds],\n type: CustomFeeType.FIXED_FEE,\n });\n\n return this;\n }\n\n /**\n * Adds a token fee configuration to the builder.\n * Allows chaining multiple fee additions.\n * Fetches token decimals automatically if not provided.\n * @param tokenAmount The amount of the specified token.\n * @param feeTokenId The ID of the token to charge the fee in.\n * @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.\n * @param decimals Optional. The number of decimals for the token. If omitted, it will be fetched from the mirror node.\n * @param exemptAccountIds Optional. Accounts specifically exempt from *this* token fee.\n * @returns A Promise resolving to this FeeConfigBuilder instance for chaining.\n */\n async addTokenFee(\n tokenAmount: number,\n feeTokenId: string,\n collectorAccountId?: string,\n decimals?: number,\n exemptAccountIds: string[] = []\n ): Promise<FeeConfigBuilder> {\n if (tokenAmount <= 0) {\n throw new Error('Token amount must be greater than zero');\n }\n if (!feeTokenId) {\n throw new Error('Fee token ID is required when adding a token fee');\n }\n\n let finalDecimals = decimals;\n if (finalDecimals === undefined) {\n try {\n const tokenInfo = await this.mirrorNode.getTokenInfo(feeTokenId);\n if (tokenInfo?.decimals) {\n finalDecimals = parseInt(tokenInfo.decimals, 10);\n this.logger.info(\n `Fetched decimals for ${feeTokenId}: ${finalDecimals}`\n );\n } else {\n this.logger.warn(\n `Could not fetch decimals for ${feeTokenId}, defaulting to 0.`\n );\n finalDecimals = 0;\n }\n } catch (error) {\n this.logger.error(\n `Error fetching decimals for ${feeTokenId}, defaulting to 0: ${error}`\n );\n finalDecimals = 0;\n }\n }\n\n this.customFees.push({\n feeAmount: {\n amount: tokenAmount * 10 ** finalDecimals,\n decimals: finalDecimals,\n },\n feeCollectorAccountId: collectorAccountId || '',\n feeTokenId: feeTokenId,\n exemptAccounts: [...exemptAccountIds],\n type: CustomFeeType.FIXED_FEE,\n });\n\n return this;\n }\n\n /**\n * Builds the final TopicFeeConfig object.\n * @returns The TopicFeeConfig containing all added custom fees and a consolidated list of unique exempt accounts.\n * @throws Error if no fees have been added.\n * @throws Error if more than 10 fees have been added.\n */\n build(): TopicFeeConfig {\n if (this.customFees.length === 0) {\n throw new Error(\n 'At least one fee must be added using addHbarFee/addTokenFee or created using forHbar/forToken'\n );\n }\n\n if (this.customFees.length > 10) {\n throw new Error('Maximum of 10 custom fees per topic allowed');\n }\n\n const allExemptAccounts = new Set<string>();\n this.customFees.forEach((fee) => {\n fee.exemptAccounts.forEach((account) => allExemptAccounts.add(account));\n });\n\n return {\n customFees: this.customFees,\n exemptAccounts: Array.from(allExemptAccounts),\n };\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"standards-sdk.es19.js","sources":["../../src/services/mirror-node.ts"],"sourcesContent":["import { PublicKey, Timestamp } from '@hashgraph/sdk';\nimport axios from 'axios';\nimport { Logger } from '../utils/logger';\nimport { HCSMessage } from '../hcs-10/base-client';\nimport { proto } from '@hashgraph/proto';\nimport {\n AccountResponse,\n CustomFees,\n HBARPrice,\n TokenInfoResponse,\n TopicMessagesResponse,\n TopicResponse,\n} from './types';\nimport { NetworkType } from '../utils/types';\nexport class HederaMirrorNode {\n private network: NetworkType;\n private baseUrl: string;\n private logger: Logger;\n private isServerEnvironment: boolean;\n\n constructor(network: NetworkType, logger: Logger) {\n this.network = network;\n this.baseUrl = this.getMirrorNodeUrl();\n this.logger = logger;\n this.isServerEnvironment = typeof window === 'undefined';\n }\n\n private getMirrorNodeUrl(): string {\n return this.network === 'mainnet'\n ? 'https://mainnet-public.mirrornode.hedera.com'\n : 'https://testnet.mirrornode.hedera.com';\n }\n\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n /**\n * Retrieves the public key for a given account ID from the mirror node.\n * @param accountId The ID of the account to retrieve the public key for.\n * @returns A promise that resolves to the public key for the given account.\n * @throws An error if the account ID is invalid or the public key cannot be retrieved.\n */\n async getPublicKey(accountId: string): Promise<PublicKey> {\n this.logger.info(`Getting public key for account ${accountId}`);\n\n const accountInfo = await this.requestAccount(accountId);\n\n try {\n if (!accountInfo || !accountInfo.key) {\n throw new Error(\n `Failed to retrieve public key for account ID: ${accountId}`\n );\n }\n\n return PublicKey.fromString(accountInfo.key.key);\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error fetching public key from Mirror Node: ${error.message}`;\n this.logger.error(logMessage);\n throw new Error(logMessage);\n }\n }\n\n /**\n * Retrieves the memo for a given account ID from the mirror node.\n * @param accountId The ID of the account to retrieve the memo for.\n * @returns A promise that resolves to the memo for the given account.\n * @throws An error if the account ID is invalid or the memo cannot be retrieved.\n */\n async getAccountMemo(accountId: string): Promise<string | null> {\n const maxRetries = 3;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n const accountInfoUrl = `${this.baseUrl}/api/v1/accounts/${accountId}`;\n\n const response = await axios.get(accountInfoUrl);\n const accountInfo = response.data;\n\n if (accountInfo && accountInfo.memo) {\n return accountInfo.memo;\n }\n\n this.logger.error(`No memo found for account ${accountId}`);\n\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error getting account memo (attempt ${attempt + 1}): ${error.message}`;\n this.logger.error(logMessage);\n\n if (attempt < maxRetries - 1) {\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n }\n }\n\n return null;\n }\n\n /**\n * Retrieves topic information for a given topic ID from the mirror node.\n * @param topicId The ID of the topic to retrieve information for.\n * @returns A promise that resolves to the topic information.\n * @throws An error if the topic ID is invalid or the information cannot be retrieved.\n */\n async getTopicInfo(topicId: string): Promise<TopicResponse> {\n try {\n const topicInfoUrl = `${this.baseUrl}/api/v1/topics/${topicId}`;\n const response = await axios.get(topicInfoUrl);\n return response.data;\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error retrieving topic information: ${error.message}`;\n this.logger.error(logMessage);\n throw new Error(logMessage);\n }\n }\n\n /**\n * Retrieves custom fees for a given topic ID from the mirror node.\n * @param topicId The ID of the topic to retrieve custom fees for.\n * @returns A promise that resolves to the custom fees for the given topic.\n * @throws An error if the topic ID is invalid or the custom fees cannot be retrieved.\n */\n async getTopicFees(topicId: string): Promise<CustomFees | null> {\n try {\n const topicInfo = await this.getTopicInfo(topicId);\n return topicInfo.custom_fees;\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error retrieving topic fees: ${error.message}`;\n this.logger.error(logMessage);\n return null;\n }\n }\n\n /**\n * Retrieves the current HBAR price from the mirror node.\n * @param date The date to retrieve the HBAR price for.\n * @returns A promise that resolves to the HBAR price for the given date.\n * @throws An error if the date is invalid or the price cannot be retrieved.\n */\n async getHBARPrice(date: Date): Promise<number | null> {\n try {\n const timestamp = Timestamp.fromDate(date).toString();\n\n const request = await fetch(\n `https://mainnet-public.mirrornode.hedera.com/api/v1/network/exchangerate?timestamp=${timestamp}`\n );\n const response = (await request.json()) as HBARPrice;\n\n const usdPrice =\n Number(response?.current_rate?.cent_equivalent) /\n Number(response?.current_rate?.hbar_equivalent) /\n 100;\n\n return usdPrice;\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error retrieving HBAR price: ${error.message}`;\n this.logger.error(logMessage);\n return null;\n }\n }\n\n /**\n * Retrieves token information for a given token ID from the mirror node.\n * @param tokenId The ID of the token to retrieve information for.\n * @returns A promise that resolves to the token information.\n * @throws An error if the token ID is invalid or the information cannot be retrieved.\n */\n async getTokenInfo(tokenId: string): Promise<TokenInfoResponse | null> {\n this.logger.debug(`Fetching token info for ${tokenId}`);\n try {\n const tokenInfoUrl = `${this.baseUrl}/api/v1/tokens/${tokenId}`;\n const response = await axios.get<TokenInfoResponse>(tokenInfoUrl);\n if (response.data) {\n this.logger.trace(`Token info found for ${tokenId}:`, response.data);\n return response.data;\n }\n this.logger.warn(`No token info found for ${tokenId}`);\n return null;\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error fetching token info for ${tokenId}: ${error.message}`;\n this.logger.error(logMessage);\n\n return null;\n }\n }\n\n /**\n * Retrieves messages for a given topic ID from the mirror node.\n * @param topicId The ID of the topic to retrieve messages for.\n * @returns A promise that resolves to the messages for the given topic.\n * @throws An error if the topic ID is invalid or the messages cannot be retrieved.\n */\n async getTopicMessages(topicId: string): Promise<HCSMessage[]> {\n this.logger.trace(`Querying messages for topic ${topicId}`);\n\n let nextUrl = `${this.baseUrl}/api/v1/topics/${topicId}/messages`;\n const messages: HCSMessage[] = [];\n\n while (nextUrl) {\n try {\n const response = await axios.get<TopicMessagesResponse>(nextUrl);\n const data = response.data;\n\n if (data.messages && data.messages.length > 0) {\n for (const message of data.messages) {\n try {\n if (!message.message) {\n continue;\n }\n\n let messageContent: string;\n try {\n if (this.isServerEnvironment) {\n messageContent = Buffer.from(\n message.message,\n 'base64'\n ).toString('utf-8');\n } else {\n messageContent = new TextDecoder().decode(\n Uint8Array.from(atob(message.message), (c) =>\n c.charCodeAt(0)\n )\n );\n }\n } catch (error) {\n const logMessage = `Error decoding message: ${error}`;\n this.logger.error(logMessage);\n continue;\n }\n\n let messageJson;\n try {\n messageJson = JSON.parse(messageContent);\n } catch (error) {\n const logMessage = `Invalid JSON message content: ${messageContent}`;\n this.logger.error(logMessage);\n return;\n }\n\n messageJson.sequence_number = message.sequence_number;\n messages.push({\n ...messageJson,\n consensus_timestamp: message.consensus_timestamp,\n sequence_number: message.sequence_number,\n created: new Date(Number(message.consensus_timestamp) * 1000),\n });\n } catch (error: any) {\n const logMessage = `Error processing message: ${error.message}`;\n this.logger.error(logMessage);\n }\n }\n }\n\n nextUrl = data.links?.next ? `${this.baseUrl}${data.links.next}` : '';\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error querying topic messages: ${error.message} on ${topicId}`;\n this.logger.error(logMessage);\n throw new Error(logMessage);\n }\n }\n\n return messages;\n }\n\n /**\n * Requests account information for a given account ID from the mirror node.\n * @param accountId The ID of the account to retrieve information for.\n * @returns A promise that resolves to the account information.\n * @throws An error if the account ID is invalid or the information cannot be retrieved.\n */\n async requestAccount(accountId: string): Promise<AccountResponse> {\n try {\n const accountInfoUrl = `${this.baseUrl}/api/v1/accounts/${accountId}`;\n const response = await axios.get(accountInfoUrl);\n if (!response.data) {\n throw new Error(\n `Failed to make request to mirror node for account: ${accountId}`\n );\n }\n return response.data;\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Failed to fetch account: ${error.message}`;\n this.logger.error(logMessage);\n throw new Error(logMessage);\n }\n }\n\n /**\n * Checks if a user has access to a given key list.\n * @param keyBytes The key list to check access for.\n * @param userPublicKey The public key of the user to check access for.\n * @returns A promise that resolves to true if the user has access, false otherwise.\n */\n async checkKeyListAccess(\n keyBytes: Buffer,\n userPublicKey: PublicKey\n ): Promise<boolean> {\n try {\n const key = proto.Key.decode(keyBytes);\n return this.evaluateKeyAccess(key, userPublicKey);\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error decoding protobuf key: ${error.message}`;\n this.logger.error(logMessage);\n throw new Error(logMessage);\n }\n }\n\n /**\n * Evaluates the access of a given key to a user's public key.\n * @param key The key to evaluate access for.\n * @param userPublicKey The public key of the user to evaluate access for.\n * @returns A promise that resolves to true if the key has access, false otherwise.\n */\n private async evaluateKeyAccess(\n key: proto.IKey,\n userPublicKey: PublicKey\n ): Promise<boolean> {\n if (key.ed25519) {\n return this.compareEd25519Key(key.ed25519, userPublicKey);\n }\n\n if (key.keyList) {\n return this.evaluateKeyList(key.keyList, userPublicKey);\n }\n\n if (key.thresholdKey && key.thresholdKey.keys) {\n return this.evaluateKeyList(key.thresholdKey.keys, userPublicKey);\n }\n\n return false;\n }\n\n /**\n * Evaluates the access of a given key list to a user's public key.\n * @param keyList The key list to evaluate access for.\n * @param userPublicKey The public key of the user to evaluate access for.\n * @returns A promise that resolves to true if the key list has access, false otherwise.\n */\n private async evaluateKeyList(\n keyList: proto.IKeyList,\n userPublicKey: PublicKey\n ): Promise<boolean> {\n const keys = keyList.keys || [];\n\n for (const listKey of keys) {\n if (!listKey) continue;\n\n if (listKey.ed25519) {\n if (this.compareEd25519Key(listKey.ed25519, userPublicKey)) {\n return true;\n }\n } else if (listKey.keyList || listKey.thresholdKey) {\n try {\n const nestedKeyBytes = proto.Key.encode({\n ...(listKey.keyList ? { keyList: listKey.keyList } : {}),\n ...(listKey.thresholdKey\n ? { thresholdKey: listKey.thresholdKey }\n : {}),\n }).finish();\n\n const hasNestedAccess = await this.checkKeyListAccess(\n Buffer.from(nestedKeyBytes),\n userPublicKey\n );\n\n if (hasNestedAccess) {\n return true;\n }\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error in nested key: ${error.message}`;\n this.logger.debug(logMessage);\n }\n }\n }\n\n return false;\n }\n\n /**\n * Compares an Ed25519 key with a user's public key.\n * @param keyData The Ed25519 key data to compare.\n * @param userPublicKey The public key of the user to compare with.\n * @returns A boolean indicating whether the key matches the user's public key.\n */\n private compareEd25519Key(\n keyData: Uint8Array,\n userPublicKey: PublicKey\n ): boolean {\n try {\n const decodedKey = PublicKey.fromBytes(Buffer.from(keyData));\n return decodedKey.toString() === userPublicKey.toString();\n } catch (e: any) {\n const error = e as Error;\n const logMessage = `Error comparing Ed25519 key: ${error.message}`;\n this.logger.debug(logMessage);\n return false;\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Logger } from "./standards-sdk.es14.js";
1
+ import { Logger } from "./standards-sdk.es15.js";
2
2
  const sleep = (ms) => {
3
3
  return new Promise((resolve) => setTimeout(resolve, ms));
4
4
  };
@@ -679,17 +679,6 @@ class HCS {
679
679
  }
680
680
  }
681
681
  }
682
- const isServer = typeof window === "undefined";
683
- if (!isServer) {
684
- window.HCS = new HCS();
685
- window.HCS.init().then(() => {
686
- console.log("All HCS resources loaded");
687
- if (typeof window.HCSReady === "function") {
688
- console.log("Running HCSReady...");
689
- window.HCSReady();
690
- }
691
- });
692
- }
693
682
  export {
694
683
  HCS,
695
684
  sleep
@@ -1 +1 @@
1
- {"version":3,"file":"standards-sdk.es2.js","sources":["../../src/hcs-3/src/index.ts"],"sourcesContent":["import {\n HCSSDK,\n LoadQueueItem,\n HCSConfigMapping,\n HCSConfig,\n LoadType,\n} from './types';\nimport { Logger } from '../../utils/logger';\n\nexport const sleep = (ms: number) => {\n return new Promise((resolve) => setTimeout(resolve, ms));\n};\n\nexport class HCS implements HCSSDK {\n config: HCSConfig;\n configMapping: HCSConfigMapping;\n LoadedScripts: Record<string, string>;\n LoadedWasm: Record<string, WebAssembly.Instance>;\n LoadedImages: Record<string, string>;\n LoadedVideos: Record<string, string>;\n LoadedAudios: Record<string, HTMLAudioElement>;\n LoadedAudioUrls: Record<string, string>;\n LoadedGLBs: Record<string, string>;\n scriptLoadedEvent: Event;\n loadQueue: LoadQueueItem[];\n isProcessingQueue: boolean;\n private modelViewerLoaded: boolean = false;\n private modelViewerLoading: Promise<void> | null = null;\n private logger: Logger;\n\n constructor() {\n this.config = {\n cdnUrl: 'https://kiloscribe.com/api/inscription-cdn/',\n network: 'mainnet',\n retryAttempts: 3,\n retryBackoff: 300,\n debug: false,\n showLoadingIndicator: false,\n loadingCallbackName: null,\n };\n this.configMapping = {\n hcsCdnUrl: 'cdnUrl',\n hcsNetwork: 'network',\n hcsRetryAttempts: 'retryAttempts',\n hcsRetryBackoff: 'retryBackoff',\n hcsDebug: 'debug',\n hcsShowLoadingIndicator: 'showLoadingIndicator',\n hcsLoadingCallbackName: 'loadingCallbackName',\n };\n this.LoadedScripts = {};\n this.LoadedWasm = {};\n this.LoadedImages = {};\n this.LoadedVideos = {};\n this.LoadedAudios = {};\n this.LoadedAudioUrls = {};\n this.LoadedGLBs = {};\n this.scriptLoadedEvent = new Event('HCSScriptLoaded');\n this.loadQueue = [] as LoadQueueItem[];\n this.isProcessingQueue = false;\n\n try {\n this.logger = Logger.getInstance({\n module: 'HCS-3',\n level: this.config.debug ? 'debug' : 'error',\n });\n } catch (e) {\n this.logger = this.createFallbackLogger();\n }\n }\n\n private createFallbackLogger(): Logger {\n const fallbackLogger = {\n debug: (...args: any[]) =>\n this.config.debug && console.debug('[HCS-3]', ...args),\n info: (...args: any[]) =>\n this.config.debug && console.info('[HCS-3]', ...args),\n warn: (...args: any[]) => console.warn('[HCS-3]', ...args),\n error: (...args: any[]) => console.error('[HCS-3]', ...args),\n setLogLevel: (level: string) => {\n this.config.debug = level === 'debug';\n },\n } as unknown as Logger;\n\n return fallbackLogger;\n }\n\n log(...args: any[]): void {\n if (args.length === 0) {\n this.logger.debug('');\n } else if (args.length === 1) {\n this.logger.debug(String(args[0]));\n } else {\n const message = String(args[0]);\n const data = args.slice(1);\n this.logger.debug(message, data);\n }\n }\n\n error(...args: any[]): void {\n if (args.length === 0) {\n this.logger.error('');\n } else if (args.length === 1) {\n this.logger.error(String(args[0]));\n } else {\n const message = String(args[0]);\n const data = args.slice(1);\n this.logger.error(message, data);\n }\n }\n\n loadConfigFromHTML(): void {\n const configScript = document.querySelector(\n 'script[data-hcs-config]'\n ) as HTMLScriptElement | null;\n if (configScript) {\n Object.keys(this.configMapping).forEach((dataAttr) => {\n if (configScript.dataset[dataAttr]) {\n const configKey =\n this.configMapping[dataAttr as keyof HCSConfigMapping];\n let value: any = configScript.dataset[dataAttr];\n\n if (value === 'true') value = true;\n if (value === 'false') value = false;\n if (!isNaN(Number(value)) && value !== '') value = Number(value);\n\n (this.config as any)[configKey] = value;\n }\n });\n\n // Update logger level based on debug setting\n this.logger.setLogLevel(this.config.debug ? 'debug' : 'error');\n }\n this.log('Loaded config:', this.config);\n }\n\n updateLoadingStatus(id: string, status: string): void {\n if (this.LoadedScripts[id] === 'loaded') {\n return;\n }\n if (this.config.showLoadingIndicator) {\n console.log('[HCS Loading] ' + id + ' : ' + status);\n }\n this.LoadedScripts[id] = status;\n if (\n this.config.loadingCallbackName &&\n typeof (window as any)[this.config.loadingCallbackName] === 'function'\n ) {\n const callback = (window as any)[this.config.loadingCallbackName];\n if (typeof callback === 'function') {\n callback(id, status);\n }\n }\n }\n\n async fetchWithRetry(\n url: string,\n retries: number = this.config.retryAttempts,\n backoff: number = this.config.retryBackoff\n ): Promise<Response> {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error('HTTP error! status: ' + response.status);\n }\n return response;\n } catch (error) {\n if (retries > 0) {\n this.log(\n 'Retrying fetch for ' + url + ' Attempts left: ' + (retries - 1)\n );\n await this.sleep(backoff);\n return this.fetchWithRetry(url, retries - 1, backoff * 2);\n }\n throw error;\n }\n }\n\n sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n isDuplicate(topicId: string): boolean {\n return !!this.LoadedScripts[topicId];\n }\n\n async retrieveHCS1Data(\n topicId: string,\n cdnUrl: string = this.config.cdnUrl,\n network: string = this.config.network\n ): Promise<Blob> {\n const cleanNetwork = network.replace(/['\"]+/g, '');\n const response = await this.fetchWithRetry(\n cdnUrl + topicId + '?network=' + cleanNetwork\n );\n return await response.blob();\n }\n\n async loadScript(scriptElement: HTMLElement): Promise<void> {\n const src = scriptElement.getAttribute('data-src');\n const scriptId = scriptElement.getAttribute('data-script-id');\n const topicId = src?.split('/').pop();\n const type = scriptElement.getAttribute('type');\n const isRequired = scriptElement.hasAttribute('data-required');\n const isModule = scriptElement.getAttribute('type') === 'module';\n\n if (this.isDuplicate(topicId || '')) {\n return;\n }\n\n this.updateLoadingStatus(scriptId!, 'loading');\n\n try {\n const cdnUrl =\n scriptElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n scriptElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n\n if (type === 'wasm') {\n const arrayBuffer = await blob.arrayBuffer();\n const wasmModule = await WebAssembly.compile(arrayBuffer);\n this.LoadedWasm[scriptId!] = await WebAssembly.instantiate(wasmModule, {\n env: {},\n ...(scriptElement.dataset as any),\n });\n this.updateLoadingStatus(scriptId!, 'loaded');\n window.dispatchEvent(this.scriptLoadedEvent);\n this.log('Loaded wasm: ' + scriptId);\n } else {\n const content = await blob.text();\n const script = document.createElement('script');\n script.textContent = content;\n script.className = 'hcs-inline-script';\n // Copy over the script ID to the inlined script\n if (scriptId) {\n script.setAttribute('data-loaded-script-id', scriptId);\n }\n\n if (isModule) {\n script.type = 'module';\n const moduleBlob = new Blob([content], {\n type: 'application/javascript',\n });\n script.src = URL.createObjectURL(moduleBlob);\n }\n\n document.body.appendChild(script);\n\n this.updateLoadingStatus(scriptId!, 'loaded');\n window.dispatchEvent(this.scriptLoadedEvent);\n this.log('Loaded script: ' + scriptId);\n\n script.onerror = (error) => {\n this.error('Failed to load ' + type + ': ' + scriptId, error);\n this.updateLoadingStatus(scriptId!, 'failed');\n if (isRequired) {\n throw error;\n }\n };\n }\n } catch (error) {\n this.error('Failed to load ' + type + ': ' + scriptId, error);\n this.updateLoadingStatus(scriptId!, 'failed');\n if (isRequired) {\n throw error;\n }\n }\n }\n\n async loadModuleExports(scriptId: string): Promise<any> {\n const script = document.querySelector(\n 'script[data-loaded-script-id=\"' + scriptId + '\"]'\n );\n if (!script) {\n throw new Error('Module script with id ' + scriptId + ' not found');\n }\n const scriptSrc = script.getAttribute('src');\n if (!scriptSrc) {\n throw new Error('Module script ' + scriptId + ' has no src attribute');\n }\n\n try {\n return await import(/* webpackIgnore: true */ scriptSrc);\n } catch (error) {\n this.error('Failed to import module', error);\n throw error;\n }\n }\n\n async loadStylesheet(linkElement: HTMLElement): Promise<void> {\n const src = linkElement.getAttribute('data-src');\n const stylesheetId = linkElement.getAttribute('data-script-id');\n const topicId = src?.split('/').pop();\n const isRequired = linkElement.hasAttribute('data-required');\n if (this.isDuplicate(topicId || '')) {\n return;\n }\n\n this.updateLoadingStatus(stylesheetId!, 'loading');\n\n try {\n const cdnUrl =\n linkElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n linkElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const cssContent = await blob.text();\n const style = document.createElement('style');\n style.textContent = cssContent;\n document.head.appendChild(style);\n\n this.updateLoadingStatus(stylesheetId!, 'loaded');\n window.dispatchEvent(this.scriptLoadedEvent);\n this.log('Loaded and inlined stylesheet: ' + stylesheetId);\n } catch (error) {\n this.error('Failed to load stylesheet: ' + stylesheetId, error);\n this.updateLoadingStatus(stylesheetId!, 'failed');\n if (isRequired) {\n throw error;\n }\n }\n }\n\n async loadImage(imageElement: HTMLElement): Promise<void> {\n const src = imageElement.getAttribute('data-src');\n const topicId = src?.split('/').pop();\n\n this.log('Loading image: ' + topicId);\n this.updateLoadingStatus('Image: ' + topicId!, 'loaded');\n\n try {\n const cdnUrl =\n imageElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n imageElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n (imageElement as HTMLImageElement).src = objectURL;\n this.LoadedImages[topicId!] = objectURL;\n this.updateLoadingStatus('Image: ' + topicId!, 'loaded');\n this.log('Loaded image: ' + topicId);\n } catch (error) {\n this.error('Failed to load image: ' + topicId, error);\n this.updateLoadingStatus('Image: ' + topicId!, 'failed');\n }\n }\n\n async loadMedia(\n mediaElement: HTMLElement,\n mediaType: 'video' | 'audio'\n ): Promise<void> {\n const src = mediaElement.getAttribute('data-src');\n const topicId = src?.split('/').pop();\n\n this.log('Loading ' + mediaType + ': ' + topicId);\n this.updateLoadingStatus(mediaType + ': ' + topicId!, 'loading');\n\n try {\n const cdnUrl =\n mediaElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n mediaElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n (mediaElement as HTMLMediaElement).src = objectURL;\n\n if (mediaType === 'video') {\n this.LoadedVideos[topicId!] = objectURL;\n } else {\n this.LoadedAudioUrls[topicId!] = objectURL;\n }\n\n this.updateLoadingStatus(mediaType + ': ' + topicId!, 'loaded');\n this.log('Loaded ' + mediaType + ': ' + topicId);\n } catch (error) {\n this.error('Failed to load ' + mediaType + ': ' + topicId, error);\n this.updateLoadingStatus(mediaType + ': ' + topicId!, 'failed');\n }\n }\n\n private async loadModelViewer(): Promise<void> {\n if (this.modelViewerLoading) return this.modelViewerLoading;\n if (this.modelViewerLoaded) return Promise.resolve();\n\n this.modelViewerLoading = new Promise<void>((resolve) => {\n const modelViewerScript = document.createElement('script');\n modelViewerScript.setAttribute('data-src', 'hcs://1/0.0.7293044');\n modelViewerScript.setAttribute('data-script-id', 'model-viewer');\n modelViewerScript.setAttribute('type', 'module');\n\n window.addEventListener(\n 'HCSScriptLoaded',\n () => {\n this.modelViewerLoaded = true;\n resolve();\n },\n { once: true }\n );\n\n this.loadScript(modelViewerScript);\n });\n\n return this.modelViewerLoading;\n }\n\n async loadGLB(glbElement: HTMLElement): Promise<void> {\n await this.loadModelViewer();\n\n const src = glbElement.getAttribute('data-src');\n const topicId = src?.split('/').pop();\n\n this.log('Loading GLB: ' + topicId);\n this.updateLoadingStatus('GLB: ' + topicId!, 'loading');\n\n try {\n const cdnUrl =\n glbElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n glbElement.getAttribute('data-network') || this.config.network;\n\n let modelViewer: HTMLElement;\n if (glbElement.tagName.toLowerCase() !== 'model-viewer') {\n modelViewer = document.createElement('model-viewer');\n Array.from(glbElement.attributes).forEach((attr) => {\n modelViewer.setAttribute(attr.name, attr.value);\n });\n modelViewer.setAttribute('camera-controls', '');\n modelViewer.setAttribute('auto-rotate', '');\n modelViewer.setAttribute('ar', '');\n glbElement.parentNode?.replaceChild(modelViewer, glbElement);\n } else {\n modelViewer = glbElement;\n }\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n modelViewer.setAttribute('src', objectURL);\n this.LoadedGLBs[topicId!] = objectURL;\n\n this.updateLoadingStatus('GLB: ' + topicId!, 'loaded');\n this.log('Loaded GLB: ' + topicId);\n } catch (error) {\n this.error('Failed to load GLB: ' + topicId, error);\n this.updateLoadingStatus('GLB: ' + topicId!, 'failed');\n }\n }\n\n async loadResource(\n element: HTMLElement,\n type: LoadType,\n order: number\n ): Promise<void> {\n return new Promise((resolve) => {\n this.loadQueue.push({ element, type, order, resolve });\n this.processQueue();\n });\n }\n\n async processQueue(): Promise<void> {\n if (this.isProcessingQueue) return;\n this.isProcessingQueue = true;\n\n while (this.loadQueue.length > 0) {\n const item = this.loadQueue.shift()!;\n try {\n if (item.type === 'script') {\n await this.loadScript(item.element);\n } else if (item.type === 'image') {\n await this.loadImage(item.element);\n } else if (item.type === 'video' || item.type === 'audio') {\n await this.loadMedia(item.element, item.type as 'video' | 'audio');\n } else if (item.type === 'glb') {\n await this.loadGLB(item.element);\n } else if (item.type === 'css') {\n await this.loadStylesheet(item.element);\n }\n item.resolve();\n } catch (error) {\n this.error('Error processing queue item:', error);\n if (\n item.type === 'script' &&\n item.element.hasAttribute('data-required')\n ) {\n break;\n }\n }\n }\n\n this.isProcessingQueue = false;\n }\n\n private async replaceHCSInStyle(styleContent: string): Promise<string> {\n let newContent = styleContent;\n let startIndex = newContent.indexOf('hcs://');\n\n while (startIndex !== -1) {\n let endIndex = startIndex;\n while (\n endIndex < newContent.length &&\n ![\"'\", '\"', ' ', ')'].includes(newContent[endIndex])\n ) {\n endIndex++;\n }\n\n const hcsUrl = newContent.substring(startIndex, endIndex);\n const topicId = hcsUrl.split('/').pop()!;\n\n try {\n const cdnUrl = this.config.cdnUrl;\n const network = this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n\n newContent =\n newContent.substring(0, startIndex) +\n objectURL +\n newContent.substring(endIndex);\n\n this.LoadedImages[topicId] = objectURL;\n this.log('Replaced CSS HCS URL: ' + hcsUrl + ' with ' + objectURL);\n } catch (error) {\n this.error('Failed to load CSS image: ' + topicId, error);\n }\n\n startIndex = newContent.indexOf('hcs://', startIndex + 1);\n }\n\n return newContent;\n }\n\n private async processInlineStyles(): Promise<void> {\n const elementsWithStyle = document.querySelectorAll('[style*=\"hcs://\"]');\n this.log(\n 'Found ' +\n elementsWithStyle.length +\n ' elements with HCS style references'\n );\n\n for (const element of Array.from(elementsWithStyle)) {\n const style = element.getAttribute('style');\n if (style) {\n this.log('Processing style: ' + style);\n const newStyle = await this.replaceHCSInStyle(style);\n if (style !== newStyle) {\n element.setAttribute('style', newStyle);\n this.log('Updated style to: ' + newStyle);\n }\n }\n }\n\n const styleTags = document.querySelectorAll('style');\n for (const styleTag of Array.from(styleTags)) {\n if (styleTag.textContent?.includes('hcs://')) {\n const newContent = await this.replaceHCSInStyle(styleTag.textContent);\n if (styleTag.textContent !== newContent) {\n styleTag.textContent = newContent;\n }\n }\n }\n }\n\n async init(): Promise<void> {\n this.loadConfigFromHTML();\n\n return new Promise((resolve) => {\n const initializeObserver = async () => {\n const scriptElements = document.querySelectorAll(\n 'script[data-src^=\"hcs://\"]'\n );\n const imageElements = document.querySelectorAll(\n 'img[data-src^=\"hcs://\"], img[src^=\"hcs://\"]'\n );\n const videoElements = document.querySelectorAll(\n 'video[data-src^=\"hcs://\"], video[src^=\"hcs://\"]'\n );\n const audioElements = document.querySelectorAll(\n 'audio[data-src^=\"hcs://\"], audio[src^=\"hcs://\"]'\n );\n const glbElements = document.querySelectorAll(\n 'model-viewer[data-src^=\"hcs://\"]'\n );\n const cssElements = document.querySelectorAll(\n 'link[data-src^=\"hcs://\"]'\n );\n\n // Convert src to data-src for HCS URLs\n document.querySelectorAll('[src^=\"hcs://\"]').forEach((element) => {\n const src = element.getAttribute('src');\n if (src) {\n element.setAttribute('data-src', src);\n element.removeAttribute('src');\n }\n });\n\n await this.processInlineStyles();\n\n const loadPromises: Promise<void>[] = [];\n\n [\n { elements: scriptElements, type: 'script' },\n { elements: imageElements, type: 'image' },\n { elements: videoElements, type: 'video' },\n { elements: audioElements, type: 'audio' },\n { elements: glbElements, type: 'glb' },\n { elements: cssElements, type: 'css' },\n ].forEach(({ elements, type }) => {\n elements.forEach((element) => {\n const order =\n parseInt(element.getAttribute('data-load-order') || '') ||\n Infinity;\n loadPromises.push(\n this.loadResource(element as HTMLElement, type as LoadType, order)\n );\n });\n });\n\n await Promise.all(loadPromises);\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n\n if (element.getAttribute('style')?.includes('hcs://')) {\n this.processInlineStyles();\n }\n\n if (\n element.tagName.toLowerCase() === 'style' &&\n element.textContent?.includes('hcs://')\n ) {\n this.processInlineStyles();\n }\n\n // Handle both src and data-src attributes\n if (element.getAttribute('src')?.startsWith('hcs://')) {\n const src = element.getAttribute('src')!;\n element.setAttribute('data-src', src);\n element.removeAttribute('src');\n\n // Immediately process the element based on its type\n const tagName = element.tagName.toLowerCase();\n switch (tagName) {\n case 'img':\n this.loadResource(element, 'image', Infinity);\n break;\n case 'video':\n this.loadResource(element, 'video', Infinity);\n break;\n case 'audio':\n this.loadResource(element, 'audio', Infinity);\n break;\n case 'script':\n this.loadResource(element, 'script', Infinity);\n break;\n }\n }\n\n // Also check data-src in case it was set directly\n if (element.matches('script[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'script', Infinity);\n } else if (element.matches('img[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'image', Infinity);\n } else if (element.matches('video[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'video', Infinity);\n } else if (element.matches('audio[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'audio', Infinity);\n } else if (\n element.matches('model-viewer[data-src^=\"hcs://\"]')\n ) {\n this.loadResource(element, 'glb', Infinity);\n } else if (element.matches('link[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'css', Infinity);\n }\n\n // Check children of added nodes for HCS URLs\n const childrenWithHCS = element.querySelectorAll(\n '[data-src^=\"hcs://\"], [src^=\"hcs://\"]'\n );\n childrenWithHCS.forEach((child) => {\n const childElement = child as HTMLElement;\n const tagName = childElement.tagName.toLowerCase();\n\n // Convert src to data-src if needed\n const src = childElement.getAttribute('src');\n if (src?.startsWith('hcs://')) {\n childElement.setAttribute('data-src', src);\n childElement.removeAttribute('src');\n }\n\n // Process based on tag type\n switch (tagName) {\n case 'script':\n this.loadResource(childElement, 'script', Infinity);\n break;\n case 'img':\n this.loadResource(childElement, 'image', Infinity);\n break;\n case 'video':\n this.loadResource(childElement, 'video', Infinity);\n break;\n case 'audio':\n this.loadResource(childElement, 'audio', Infinity);\n break;\n case 'model-viewer':\n this.loadResource(childElement, 'glb', Infinity);\n break;\n case 'link':\n this.loadResource(childElement, 'css', Infinity);\n break;\n }\n });\n }\n });\n\n // Handle attribute changes\n if (mutation.type === 'attributes') {\n const element = mutation.target as HTMLElement;\n if (\n mutation.attributeName === 'style' &&\n element.getAttribute('style')?.includes('hcs://')\n ) {\n this.processInlineStyles();\n } else if (mutation.attributeName === 'src') {\n const src = element.getAttribute('src');\n if (src?.startsWith('hcs://')) {\n element.setAttribute('data-src', src);\n element.removeAttribute('src');\n const type = element.tagName.toLowerCase();\n if (['img', 'video', 'audio'].includes(type)) {\n this.loadResource(element, type as LoadType, Infinity);\n }\n }\n }\n }\n });\n });\n\n if (document.body) {\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'src', 'data-src'],\n });\n } else {\n document.addEventListener('DOMContentLoaded', () => {\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'src', 'data-src'],\n });\n });\n }\n\n resolve();\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializeObserver);\n } else {\n initializeObserver();\n }\n });\n }\n\n async preloadImage(topicId: string): Promise<string> {\n this.log('Loading image:' + topicId);\n this.updateLoadingStatus('image: ' + topicId, 'loading');\n const blob = await this.retrieveHCS1Data(topicId);\n const objectURL = URL.createObjectURL(blob);\n this.LoadedImages[topicId!] = objectURL;\n this.updateLoadingStatus('image: ' + topicId, 'loaded');\n return objectURL;\n }\n\n async preloadAudio(topicId: string): Promise<string> {\n const audioElement = document.createElement('audio');\n audioElement.setAttribute('data-topic-id', topicId);\n audioElement.setAttribute('data-src', 'hcs://1/' + topicId);\n document.body.appendChild(audioElement);\n\n await this.loadMedia(audioElement, 'audio');\n\n const cachedAudio = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n\n if (cachedAudio) {\n this.LoadedAudioUrls[topicId] = cachedAudio.src;\n } else {\n console.error('Failed to preload audio: ' + topicId);\n }\n return this.LoadedAudioUrls[topicId];\n }\n\n async playAudio(topicId: string, volume = 1.0) {\n const audioUrl = this.LoadedAudioUrls[topicId];\n\n if (audioUrl) {\n const audio = new Audio(audioUrl);\n audio.volume = volume;\n this.LoadedAudios[topicId] = audio;\n\n audio.play().catch((error) => {\n console.error('Failed to play audio:', error);\n });\n\n audio.addEventListener('ended', () => {\n audio.remove();\n delete this.LoadedAudios[topicId];\n });\n } else {\n console.error('Audio not preloaded: ' + topicId);\n }\n }\n\n async pauseAudio(topicId: string) {\n const audioElement = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n\n if (audioElement) {\n console.log('found element', audioElement);\n audioElement.pause();\n this.LoadedAudios[topicId]?.pause();\n } else {\n this.LoadedAudios[topicId]?.pause();\n }\n }\n\n async loadAndPlayAudio(topicId: string, autoplay = false, volume = 1.0) {\n let existingAudioElement = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n\n if (existingAudioElement) {\n existingAudioElement.volume = volume;\n await existingAudioElement.play();\n } else {\n const audioElement = document.createElement('audio');\n audioElement.volume = volume;\n if (autoplay) {\n audioElement.setAttribute('autoplay', 'autoplay');\n }\n audioElement.setAttribute('data-topic-id', topicId);\n audioElement.setAttribute('data-src', 'hcs://1/' + topicId);\n\n document.body.appendChild(audioElement);\n\n await this.loadMedia(audioElement, 'audio');\n\n existingAudioElement = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n if (!autoplay) {\n await existingAudioElement.play();\n }\n }\n }\n}\nconst isServer = typeof window === 'undefined';\n\nif (!isServer) {\n (window as any).HCS = new HCS();\n (window as any).HCS.init().then(() => {\n console.log('All HCS resources loaded');\n if (typeof (window as any).HCSReady === 'function') {\n console.log('Running HCSReady...');\n (window as any).HCSReady();\n }\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"standards-sdk.es2.js","sources":["../../src/hcs-3/src/index.ts"],"sourcesContent":["import {\n HCSSDK,\n LoadQueueItem,\n HCSConfigMapping,\n HCSConfig,\n LoadType,\n} from './types';\nimport { Logger } from '../../utils/logger';\n\nexport const sleep = (ms: number) => {\n return new Promise((resolve) => setTimeout(resolve, ms));\n};\n\nexport class HCS implements HCSSDK {\n config: HCSConfig;\n configMapping: HCSConfigMapping;\n LoadedScripts: Record<string, string>;\n LoadedWasm: Record<string, WebAssembly.Instance>;\n LoadedImages: Record<string, string>;\n LoadedVideos: Record<string, string>;\n LoadedAudios: Record<string, HTMLAudioElement>;\n LoadedAudioUrls: Record<string, string>;\n LoadedGLBs: Record<string, string>;\n scriptLoadedEvent: Event;\n loadQueue: LoadQueueItem[];\n isProcessingQueue: boolean;\n private modelViewerLoaded: boolean = false;\n private modelViewerLoading: Promise<void> | null = null;\n private logger: Logger;\n\n constructor() {\n this.config = {\n cdnUrl: 'https://kiloscribe.com/api/inscription-cdn/',\n network: 'mainnet',\n retryAttempts: 3,\n retryBackoff: 300,\n debug: false,\n showLoadingIndicator: false,\n loadingCallbackName: null,\n };\n this.configMapping = {\n hcsCdnUrl: 'cdnUrl',\n hcsNetwork: 'network',\n hcsRetryAttempts: 'retryAttempts',\n hcsRetryBackoff: 'retryBackoff',\n hcsDebug: 'debug',\n hcsShowLoadingIndicator: 'showLoadingIndicator',\n hcsLoadingCallbackName: 'loadingCallbackName',\n };\n this.LoadedScripts = {};\n this.LoadedWasm = {};\n this.LoadedImages = {};\n this.LoadedVideos = {};\n this.LoadedAudios = {};\n this.LoadedAudioUrls = {};\n this.LoadedGLBs = {};\n this.scriptLoadedEvent = new Event('HCSScriptLoaded');\n this.loadQueue = [] as LoadQueueItem[];\n this.isProcessingQueue = false;\n\n try {\n this.logger = Logger.getInstance({\n module: 'HCS-3',\n level: this.config.debug ? 'debug' : 'error',\n });\n } catch (e) {\n this.logger = this.createFallbackLogger();\n }\n }\n\n private createFallbackLogger(): Logger {\n const fallbackLogger = {\n debug: (...args: any[]) =>\n this.config.debug && console.debug('[HCS-3]', ...args),\n info: (...args: any[]) =>\n this.config.debug && console.info('[HCS-3]', ...args),\n warn: (...args: any[]) => console.warn('[HCS-3]', ...args),\n error: (...args: any[]) => console.error('[HCS-3]', ...args),\n setLogLevel: (level: string) => {\n this.config.debug = level === 'debug';\n },\n } as unknown as Logger;\n\n return fallbackLogger;\n }\n\n log(...args: any[]): void {\n if (args.length === 0) {\n this.logger.debug('');\n } else if (args.length === 1) {\n this.logger.debug(String(args[0]));\n } else {\n const message = String(args[0]);\n const data = args.slice(1);\n this.logger.debug(message, data);\n }\n }\n\n error(...args: any[]): void {\n if (args.length === 0) {\n this.logger.error('');\n } else if (args.length === 1) {\n this.logger.error(String(args[0]));\n } else {\n const message = String(args[0]);\n const data = args.slice(1);\n this.logger.error(message, data);\n }\n }\n\n loadConfigFromHTML(): void {\n const configScript = document.querySelector(\n 'script[data-hcs-config]'\n ) as HTMLScriptElement | null;\n if (configScript) {\n Object.keys(this.configMapping).forEach((dataAttr) => {\n if (configScript.dataset[dataAttr]) {\n const configKey =\n this.configMapping[dataAttr as keyof HCSConfigMapping];\n let value: any = configScript.dataset[dataAttr];\n\n if (value === 'true') value = true;\n if (value === 'false') value = false;\n if (!isNaN(Number(value)) && value !== '') value = Number(value);\n\n (this.config as any)[configKey] = value;\n }\n });\n\n // Update logger level based on debug setting\n this.logger.setLogLevel(this.config.debug ? 'debug' : 'error');\n }\n this.log('Loaded config:', this.config);\n }\n\n updateLoadingStatus(id: string, status: string): void {\n if (this.LoadedScripts[id] === 'loaded') {\n return;\n }\n if (this.config.showLoadingIndicator) {\n console.log('[HCS Loading] ' + id + ' : ' + status);\n }\n this.LoadedScripts[id] = status;\n if (\n this.config.loadingCallbackName &&\n typeof (window as any)[this.config.loadingCallbackName] === 'function'\n ) {\n const callback = (window as any)[this.config.loadingCallbackName];\n if (typeof callback === 'function') {\n callback(id, status);\n }\n }\n }\n\n async fetchWithRetry(\n url: string,\n retries: number = this.config.retryAttempts,\n backoff: number = this.config.retryBackoff\n ): Promise<Response> {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error('HTTP error! status: ' + response.status);\n }\n return response;\n } catch (error) {\n if (retries > 0) {\n this.log(\n 'Retrying fetch for ' + url + ' Attempts left: ' + (retries - 1)\n );\n await this.sleep(backoff);\n return this.fetchWithRetry(url, retries - 1, backoff * 2);\n }\n throw error;\n }\n }\n\n sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n isDuplicate(topicId: string): boolean {\n return !!this.LoadedScripts[topicId];\n }\n\n async retrieveHCS1Data(\n topicId: string,\n cdnUrl: string = this.config.cdnUrl,\n network: string = this.config.network\n ): Promise<Blob> {\n const cleanNetwork = network.replace(/['\"]+/g, '');\n const response = await this.fetchWithRetry(\n cdnUrl + topicId + '?network=' + cleanNetwork\n );\n return await response.blob();\n }\n\n async loadScript(scriptElement: HTMLElement): Promise<void> {\n const src = scriptElement.getAttribute('data-src');\n const scriptId = scriptElement.getAttribute('data-script-id');\n const topicId = src?.split('/').pop();\n const type = scriptElement.getAttribute('type');\n const isRequired = scriptElement.hasAttribute('data-required');\n const isModule = scriptElement.getAttribute('type') === 'module';\n\n if (this.isDuplicate(topicId || '')) {\n return;\n }\n\n this.updateLoadingStatus(scriptId!, 'loading');\n\n try {\n const cdnUrl =\n scriptElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n scriptElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n\n if (type === 'wasm') {\n const arrayBuffer = await blob.arrayBuffer();\n const wasmModule = await WebAssembly.compile(arrayBuffer);\n this.LoadedWasm[scriptId!] = await WebAssembly.instantiate(wasmModule, {\n env: {},\n ...(scriptElement.dataset as any),\n });\n this.updateLoadingStatus(scriptId!, 'loaded');\n window.dispatchEvent(this.scriptLoadedEvent);\n this.log('Loaded wasm: ' + scriptId);\n } else {\n const content = await blob.text();\n const script = document.createElement('script');\n script.textContent = content;\n script.className = 'hcs-inline-script';\n // Copy over the script ID to the inlined script\n if (scriptId) {\n script.setAttribute('data-loaded-script-id', scriptId);\n }\n\n if (isModule) {\n script.type = 'module';\n const moduleBlob = new Blob([content], {\n type: 'application/javascript',\n });\n script.src = URL.createObjectURL(moduleBlob);\n }\n\n document.body.appendChild(script);\n\n this.updateLoadingStatus(scriptId!, 'loaded');\n window.dispatchEvent(this.scriptLoadedEvent);\n this.log('Loaded script: ' + scriptId);\n\n script.onerror = (error) => {\n this.error('Failed to load ' + type + ': ' + scriptId, error);\n this.updateLoadingStatus(scriptId!, 'failed');\n if (isRequired) {\n throw error;\n }\n };\n }\n } catch (error) {\n this.error('Failed to load ' + type + ': ' + scriptId, error);\n this.updateLoadingStatus(scriptId!, 'failed');\n if (isRequired) {\n throw error;\n }\n }\n }\n\n async loadModuleExports(scriptId: string): Promise<any> {\n const script = document.querySelector(\n 'script[data-loaded-script-id=\"' + scriptId + '\"]'\n );\n if (!script) {\n throw new Error('Module script with id ' + scriptId + ' not found');\n }\n const scriptSrc = script.getAttribute('src');\n if (!scriptSrc) {\n throw new Error('Module script ' + scriptId + ' has no src attribute');\n }\n\n try {\n return await import(/* webpackIgnore: true */ scriptSrc);\n } catch (error) {\n this.error('Failed to import module', error);\n throw error;\n }\n }\n\n async loadStylesheet(linkElement: HTMLElement): Promise<void> {\n const src = linkElement.getAttribute('data-src');\n const stylesheetId = linkElement.getAttribute('data-script-id');\n const topicId = src?.split('/').pop();\n const isRequired = linkElement.hasAttribute('data-required');\n if (this.isDuplicate(topicId || '')) {\n return;\n }\n\n this.updateLoadingStatus(stylesheetId!, 'loading');\n\n try {\n const cdnUrl =\n linkElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n linkElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const cssContent = await blob.text();\n const style = document.createElement('style');\n style.textContent = cssContent;\n document.head.appendChild(style);\n\n this.updateLoadingStatus(stylesheetId!, 'loaded');\n window.dispatchEvent(this.scriptLoadedEvent);\n this.log('Loaded and inlined stylesheet: ' + stylesheetId);\n } catch (error) {\n this.error('Failed to load stylesheet: ' + stylesheetId, error);\n this.updateLoadingStatus(stylesheetId!, 'failed');\n if (isRequired) {\n throw error;\n }\n }\n }\n\n async loadImage(imageElement: HTMLElement): Promise<void> {\n const src = imageElement.getAttribute('data-src');\n const topicId = src?.split('/').pop();\n\n this.log('Loading image: ' + topicId);\n this.updateLoadingStatus('Image: ' + topicId!, 'loaded');\n\n try {\n const cdnUrl =\n imageElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n imageElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n (imageElement as HTMLImageElement).src = objectURL;\n this.LoadedImages[topicId!] = objectURL;\n this.updateLoadingStatus('Image: ' + topicId!, 'loaded');\n this.log('Loaded image: ' + topicId);\n } catch (error) {\n this.error('Failed to load image: ' + topicId, error);\n this.updateLoadingStatus('Image: ' + topicId!, 'failed');\n }\n }\n\n async loadMedia(\n mediaElement: HTMLElement,\n mediaType: 'video' | 'audio'\n ): Promise<void> {\n const src = mediaElement.getAttribute('data-src');\n const topicId = src?.split('/').pop();\n\n this.log('Loading ' + mediaType + ': ' + topicId);\n this.updateLoadingStatus(mediaType + ': ' + topicId!, 'loading');\n\n try {\n const cdnUrl =\n mediaElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n mediaElement.getAttribute('data-network') || this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n (mediaElement as HTMLMediaElement).src = objectURL;\n\n if (mediaType === 'video') {\n this.LoadedVideos[topicId!] = objectURL;\n } else {\n this.LoadedAudioUrls[topicId!] = objectURL;\n }\n\n this.updateLoadingStatus(mediaType + ': ' + topicId!, 'loaded');\n this.log('Loaded ' + mediaType + ': ' + topicId);\n } catch (error) {\n this.error('Failed to load ' + mediaType + ': ' + topicId, error);\n this.updateLoadingStatus(mediaType + ': ' + topicId!, 'failed');\n }\n }\n\n private async loadModelViewer(): Promise<void> {\n if (this.modelViewerLoading) return this.modelViewerLoading;\n if (this.modelViewerLoaded) return Promise.resolve();\n\n this.modelViewerLoading = new Promise<void>((resolve) => {\n const modelViewerScript = document.createElement('script');\n modelViewerScript.setAttribute('data-src', 'hcs://1/0.0.7293044');\n modelViewerScript.setAttribute('data-script-id', 'model-viewer');\n modelViewerScript.setAttribute('type', 'module');\n\n window.addEventListener(\n 'HCSScriptLoaded',\n () => {\n this.modelViewerLoaded = true;\n resolve();\n },\n { once: true }\n );\n\n this.loadScript(modelViewerScript);\n });\n\n return this.modelViewerLoading;\n }\n\n async loadGLB(glbElement: HTMLElement): Promise<void> {\n await this.loadModelViewer();\n\n const src = glbElement.getAttribute('data-src');\n const topicId = src?.split('/').pop();\n\n this.log('Loading GLB: ' + topicId);\n this.updateLoadingStatus('GLB: ' + topicId!, 'loading');\n\n try {\n const cdnUrl =\n glbElement.getAttribute('data-cdn-url') || this.config.cdnUrl;\n const network =\n glbElement.getAttribute('data-network') || this.config.network;\n\n let modelViewer: HTMLElement;\n if (glbElement.tagName.toLowerCase() !== 'model-viewer') {\n modelViewer = document.createElement('model-viewer');\n Array.from(glbElement.attributes).forEach((attr) => {\n modelViewer.setAttribute(attr.name, attr.value);\n });\n modelViewer.setAttribute('camera-controls', '');\n modelViewer.setAttribute('auto-rotate', '');\n modelViewer.setAttribute('ar', '');\n glbElement.parentNode?.replaceChild(modelViewer, glbElement);\n } else {\n modelViewer = glbElement;\n }\n\n const blob = await this.retrieveHCS1Data(topicId!, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n modelViewer.setAttribute('src', objectURL);\n this.LoadedGLBs[topicId!] = objectURL;\n\n this.updateLoadingStatus('GLB: ' + topicId!, 'loaded');\n this.log('Loaded GLB: ' + topicId);\n } catch (error) {\n this.error('Failed to load GLB: ' + topicId, error);\n this.updateLoadingStatus('GLB: ' + topicId!, 'failed');\n }\n }\n\n async loadResource(\n element: HTMLElement,\n type: LoadType,\n order: number\n ): Promise<void> {\n return new Promise((resolve) => {\n this.loadQueue.push({ element, type, order, resolve });\n this.processQueue();\n });\n }\n\n async processQueue(): Promise<void> {\n if (this.isProcessingQueue) return;\n this.isProcessingQueue = true;\n\n while (this.loadQueue.length > 0) {\n const item = this.loadQueue.shift()!;\n try {\n if (item.type === 'script') {\n await this.loadScript(item.element);\n } else if (item.type === 'image') {\n await this.loadImage(item.element);\n } else if (item.type === 'video' || item.type === 'audio') {\n await this.loadMedia(item.element, item.type as 'video' | 'audio');\n } else if (item.type === 'glb') {\n await this.loadGLB(item.element);\n } else if (item.type === 'css') {\n await this.loadStylesheet(item.element);\n }\n item.resolve();\n } catch (error) {\n this.error('Error processing queue item:', error);\n if (\n item.type === 'script' &&\n item.element.hasAttribute('data-required')\n ) {\n break;\n }\n }\n }\n\n this.isProcessingQueue = false;\n }\n\n private async replaceHCSInStyle(styleContent: string): Promise<string> {\n let newContent = styleContent;\n let startIndex = newContent.indexOf('hcs://');\n\n while (startIndex !== -1) {\n let endIndex = startIndex;\n while (\n endIndex < newContent.length &&\n ![\"'\", '\"', ' ', ')'].includes(newContent[endIndex])\n ) {\n endIndex++;\n }\n\n const hcsUrl = newContent.substring(startIndex, endIndex);\n const topicId = hcsUrl.split('/').pop()!;\n\n try {\n const cdnUrl = this.config.cdnUrl;\n const network = this.config.network;\n\n const blob = await this.retrieveHCS1Data(topicId, cdnUrl, network);\n const objectURL = URL.createObjectURL(blob);\n\n newContent =\n newContent.substring(0, startIndex) +\n objectURL +\n newContent.substring(endIndex);\n\n this.LoadedImages[topicId] = objectURL;\n this.log('Replaced CSS HCS URL: ' + hcsUrl + ' with ' + objectURL);\n } catch (error) {\n this.error('Failed to load CSS image: ' + topicId, error);\n }\n\n startIndex = newContent.indexOf('hcs://', startIndex + 1);\n }\n\n return newContent;\n }\n\n private async processInlineStyles(): Promise<void> {\n const elementsWithStyle = document.querySelectorAll('[style*=\"hcs://\"]');\n this.log(\n 'Found ' +\n elementsWithStyle.length +\n ' elements with HCS style references'\n );\n\n for (const element of Array.from(elementsWithStyle)) {\n const style = element.getAttribute('style');\n if (style) {\n this.log('Processing style: ' + style);\n const newStyle = await this.replaceHCSInStyle(style);\n if (style !== newStyle) {\n element.setAttribute('style', newStyle);\n this.log('Updated style to: ' + newStyle);\n }\n }\n }\n\n const styleTags = document.querySelectorAll('style');\n for (const styleTag of Array.from(styleTags)) {\n if (styleTag.textContent?.includes('hcs://')) {\n const newContent = await this.replaceHCSInStyle(styleTag.textContent);\n if (styleTag.textContent !== newContent) {\n styleTag.textContent = newContent;\n }\n }\n }\n }\n\n async init(): Promise<void> {\n this.loadConfigFromHTML();\n\n return new Promise((resolve) => {\n const initializeObserver = async () => {\n const scriptElements = document.querySelectorAll(\n 'script[data-src^=\"hcs://\"]'\n );\n const imageElements = document.querySelectorAll(\n 'img[data-src^=\"hcs://\"], img[src^=\"hcs://\"]'\n );\n const videoElements = document.querySelectorAll(\n 'video[data-src^=\"hcs://\"], video[src^=\"hcs://\"]'\n );\n const audioElements = document.querySelectorAll(\n 'audio[data-src^=\"hcs://\"], audio[src^=\"hcs://\"]'\n );\n const glbElements = document.querySelectorAll(\n 'model-viewer[data-src^=\"hcs://\"]'\n );\n const cssElements = document.querySelectorAll(\n 'link[data-src^=\"hcs://\"]'\n );\n\n // Convert src to data-src for HCS URLs\n document.querySelectorAll('[src^=\"hcs://\"]').forEach((element) => {\n const src = element.getAttribute('src');\n if (src) {\n element.setAttribute('data-src', src);\n element.removeAttribute('src');\n }\n });\n\n await this.processInlineStyles();\n\n const loadPromises: Promise<void>[] = [];\n\n [\n { elements: scriptElements, type: 'script' },\n { elements: imageElements, type: 'image' },\n { elements: videoElements, type: 'video' },\n { elements: audioElements, type: 'audio' },\n { elements: glbElements, type: 'glb' },\n { elements: cssElements, type: 'css' },\n ].forEach(({ elements, type }) => {\n elements.forEach((element) => {\n const order =\n parseInt(element.getAttribute('data-load-order') || '') ||\n Infinity;\n loadPromises.push(\n this.loadResource(element as HTMLElement, type as LoadType, order)\n );\n });\n });\n\n await Promise.all(loadPromises);\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n\n if (element.getAttribute('style')?.includes('hcs://')) {\n this.processInlineStyles();\n }\n\n if (\n element.tagName.toLowerCase() === 'style' &&\n element.textContent?.includes('hcs://')\n ) {\n this.processInlineStyles();\n }\n\n // Handle both src and data-src attributes\n if (element.getAttribute('src')?.startsWith('hcs://')) {\n const src = element.getAttribute('src')!;\n element.setAttribute('data-src', src);\n element.removeAttribute('src');\n\n // Immediately process the element based on its type\n const tagName = element.tagName.toLowerCase();\n switch (tagName) {\n case 'img':\n this.loadResource(element, 'image', Infinity);\n break;\n case 'video':\n this.loadResource(element, 'video', Infinity);\n break;\n case 'audio':\n this.loadResource(element, 'audio', Infinity);\n break;\n case 'script':\n this.loadResource(element, 'script', Infinity);\n break;\n }\n }\n\n // Also check data-src in case it was set directly\n if (element.matches('script[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'script', Infinity);\n } else if (element.matches('img[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'image', Infinity);\n } else if (element.matches('video[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'video', Infinity);\n } else if (element.matches('audio[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'audio', Infinity);\n } else if (\n element.matches('model-viewer[data-src^=\"hcs://\"]')\n ) {\n this.loadResource(element, 'glb', Infinity);\n } else if (element.matches('link[data-src^=\"hcs://\"]')) {\n this.loadResource(element, 'css', Infinity);\n }\n\n // Check children of added nodes for HCS URLs\n const childrenWithHCS = element.querySelectorAll(\n '[data-src^=\"hcs://\"], [src^=\"hcs://\"]'\n );\n childrenWithHCS.forEach((child) => {\n const childElement = child as HTMLElement;\n const tagName = childElement.tagName.toLowerCase();\n\n // Convert src to data-src if needed\n const src = childElement.getAttribute('src');\n if (src?.startsWith('hcs://')) {\n childElement.setAttribute('data-src', src);\n childElement.removeAttribute('src');\n }\n\n // Process based on tag type\n switch (tagName) {\n case 'script':\n this.loadResource(childElement, 'script', Infinity);\n break;\n case 'img':\n this.loadResource(childElement, 'image', Infinity);\n break;\n case 'video':\n this.loadResource(childElement, 'video', Infinity);\n break;\n case 'audio':\n this.loadResource(childElement, 'audio', Infinity);\n break;\n case 'model-viewer':\n this.loadResource(childElement, 'glb', Infinity);\n break;\n case 'link':\n this.loadResource(childElement, 'css', Infinity);\n break;\n }\n });\n }\n });\n\n // Handle attribute changes\n if (mutation.type === 'attributes') {\n const element = mutation.target as HTMLElement;\n if (\n mutation.attributeName === 'style' &&\n element.getAttribute('style')?.includes('hcs://')\n ) {\n this.processInlineStyles();\n } else if (mutation.attributeName === 'src') {\n const src = element.getAttribute('src');\n if (src?.startsWith('hcs://')) {\n element.setAttribute('data-src', src);\n element.removeAttribute('src');\n const type = element.tagName.toLowerCase();\n if (['img', 'video', 'audio'].includes(type)) {\n this.loadResource(element, type as LoadType, Infinity);\n }\n }\n }\n }\n });\n });\n\n if (document.body) {\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'src', 'data-src'],\n });\n } else {\n document.addEventListener('DOMContentLoaded', () => {\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'src', 'data-src'],\n });\n });\n }\n\n resolve();\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializeObserver);\n } else {\n initializeObserver();\n }\n });\n }\n\n async preloadImage(topicId: string): Promise<string> {\n this.log('Loading image:' + topicId);\n this.updateLoadingStatus('image: ' + topicId, 'loading');\n const blob = await this.retrieveHCS1Data(topicId);\n const objectURL = URL.createObjectURL(blob);\n this.LoadedImages[topicId!] = objectURL;\n this.updateLoadingStatus('image: ' + topicId, 'loaded');\n return objectURL;\n }\n\n async preloadAudio(topicId: string): Promise<string> {\n const audioElement = document.createElement('audio');\n audioElement.setAttribute('data-topic-id', topicId);\n audioElement.setAttribute('data-src', 'hcs://1/' + topicId);\n document.body.appendChild(audioElement);\n\n await this.loadMedia(audioElement, 'audio');\n\n const cachedAudio = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n\n if (cachedAudio) {\n this.LoadedAudioUrls[topicId] = cachedAudio.src;\n } else {\n console.error('Failed to preload audio: ' + topicId);\n }\n return this.LoadedAudioUrls[topicId];\n }\n\n async playAudio(topicId: string, volume = 1.0) {\n const audioUrl = this.LoadedAudioUrls[topicId];\n\n if (audioUrl) {\n const audio = new Audio(audioUrl);\n audio.volume = volume;\n this.LoadedAudios[topicId] = audio;\n\n audio.play().catch((error) => {\n console.error('Failed to play audio:', error);\n });\n\n audio.addEventListener('ended', () => {\n audio.remove();\n delete this.LoadedAudios[topicId];\n });\n } else {\n console.error('Audio not preloaded: ' + topicId);\n }\n }\n\n async pauseAudio(topicId: string) {\n const audioElement = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n\n if (audioElement) {\n console.log('found element', audioElement);\n audioElement.pause();\n this.LoadedAudios[topicId]?.pause();\n } else {\n this.LoadedAudios[topicId]?.pause();\n }\n }\n\n async loadAndPlayAudio(topicId: string, autoplay = false, volume = 1.0) {\n let existingAudioElement = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n\n if (existingAudioElement) {\n existingAudioElement.volume = volume;\n await existingAudioElement.play();\n } else {\n const audioElement = document.createElement('audio');\n audioElement.volume = volume;\n if (autoplay) {\n audioElement.setAttribute('autoplay', 'autoplay');\n }\n audioElement.setAttribute('data-topic-id', topicId);\n audioElement.setAttribute('data-src', 'hcs://1/' + topicId);\n\n document.body.appendChild(audioElement);\n\n await this.loadMedia(audioElement, 'audio');\n\n existingAudioElement = document.querySelector(\n 'audio[data-topic-id=\"' + topicId + '\"]'\n ) as HTMLAudioElement;\n if (!autoplay) {\n await existingAudioElement.play();\n }\n }\n }\n}\n\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,158 @@
1
- var CustomFeeType = /* @__PURE__ */ ((CustomFeeType2) => {
2
- CustomFeeType2["FIXED_FEE"] = "FIXED_FEE";
3
- CustomFeeType2["FRACTIONAL_FEE"] = "FRACTIONAL_FEE";
4
- CustomFeeType2["ROYALTY_FEE"] = "ROYALTY_FEE";
5
- return CustomFeeType2;
6
- })(CustomFeeType || {});
1
+ import { CustomFeeType } from "./standards-sdk.es21.js";
2
+ import { HederaMirrorNode } from "./standards-sdk.es19.js";
3
+ class FeeConfigBuilder {
4
+ constructor(options) {
5
+ this.customFees = [];
6
+ this.logger = options.logger;
7
+ this.mirrorNode = new HederaMirrorNode(options.network, options.logger);
8
+ this.defaultCollectorAccountId = options.defaultCollectorAccountId || "";
9
+ }
10
+ /**
11
+ * Static factory method to create a FeeConfigBuilder with a single HBAR fee.
12
+ * @param hbarAmount Amount in HBAR.
13
+ * @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.
14
+ * @param network Network type ('mainnet' or 'testnet').
15
+ * @param logger Logger instance.
16
+ * @param exemptAccounts Optional array of account IDs exempt from this fee.
17
+ * @returns A configured FeeConfigBuilder instance.
18
+ */
19
+ static forHbar(hbarAmount, collectorAccountId, network, logger, exemptAccounts = []) {
20
+ const builder = new FeeConfigBuilder({
21
+ network,
22
+ logger,
23
+ defaultCollectorAccountId: collectorAccountId
24
+ });
25
+ return builder.addHbarFee(hbarAmount, collectorAccountId, exemptAccounts);
26
+ }
27
+ /**
28
+ * Static factory method to create a FeeConfigBuilder with a single token fee.
29
+ * Automatically fetches token decimals if not provided.
30
+ * @param tokenAmount Amount of tokens.
31
+ * @param feeTokenId Token ID for the fee.
32
+ * @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.
33
+ * @param network Network type ('mainnet' or 'testnet').
34
+ * @param logger Logger instance.
35
+ * @param exemptAccounts Optional array of account IDs exempt from this fee.
36
+ * @param decimals Optional decimals for the token (fetched if omitted).
37
+ * @returns A Promise resolving to a configured FeeConfigBuilder instance.
38
+ */
39
+ static async forToken(tokenAmount, feeTokenId, collectorAccountId, network, logger, exemptAccounts = [], decimals) {
40
+ const builder = new FeeConfigBuilder({
41
+ network,
42
+ logger,
43
+ defaultCollectorAccountId: collectorAccountId
44
+ });
45
+ await builder.addTokenFee(
46
+ tokenAmount,
47
+ feeTokenId,
48
+ collectorAccountId,
49
+ decimals,
50
+ exemptAccounts
51
+ );
52
+ return builder;
53
+ }
54
+ /**
55
+ * Adds an HBAR fee configuration to the builder.
56
+ * Allows chaining multiple fee additions.
57
+ * @param hbarAmount The amount in HBAR (e.g., 0.5).
58
+ * @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.
59
+ * @param exemptAccountIds Optional. Accounts specifically exempt from *this* HBAR fee.
60
+ * @returns This FeeConfigBuilder instance for chaining.
61
+ */
62
+ addHbarFee(hbarAmount, collectorAccountId, exemptAccountIds = []) {
63
+ if (hbarAmount <= 0) {
64
+ throw new Error("HBAR amount must be greater than zero");
65
+ }
66
+ this.customFees.push({
67
+ feeAmount: {
68
+ amount: hbarAmount * 1e8,
69
+ decimals: 0
70
+ },
71
+ feeCollectorAccountId: collectorAccountId || "",
72
+ feeTokenId: void 0,
73
+ exemptAccounts: [...exemptAccountIds],
74
+ type: CustomFeeType.FIXED_FEE
75
+ });
76
+ return this;
77
+ }
78
+ /**
79
+ * Adds a token fee configuration to the builder.
80
+ * Allows chaining multiple fee additions.
81
+ * Fetches token decimals automatically if not provided.
82
+ * @param tokenAmount The amount of the specified token.
83
+ * @param feeTokenId The ID of the token to charge the fee in.
84
+ * @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.
85
+ * @param decimals Optional. The number of decimals for the token. If omitted, it will be fetched from the mirror node.
86
+ * @param exemptAccountIds Optional. Accounts specifically exempt from *this* token fee.
87
+ * @returns A Promise resolving to this FeeConfigBuilder instance for chaining.
88
+ */
89
+ async addTokenFee(tokenAmount, feeTokenId, collectorAccountId, decimals, exemptAccountIds = []) {
90
+ if (tokenAmount <= 0) {
91
+ throw new Error("Token amount must be greater than zero");
92
+ }
93
+ if (!feeTokenId) {
94
+ throw new Error("Fee token ID is required when adding a token fee");
95
+ }
96
+ let finalDecimals = decimals;
97
+ if (finalDecimals === void 0) {
98
+ try {
99
+ const tokenInfo = await this.mirrorNode.getTokenInfo(feeTokenId);
100
+ if (tokenInfo?.decimals) {
101
+ finalDecimals = parseInt(tokenInfo.decimals, 10);
102
+ this.logger.info(
103
+ `Fetched decimals for ${feeTokenId}: ${finalDecimals}`
104
+ );
105
+ } else {
106
+ this.logger.warn(
107
+ `Could not fetch decimals for ${feeTokenId}, defaulting to 0.`
108
+ );
109
+ finalDecimals = 0;
110
+ }
111
+ } catch (error) {
112
+ this.logger.error(
113
+ `Error fetching decimals for ${feeTokenId}, defaulting to 0: ${error}`
114
+ );
115
+ finalDecimals = 0;
116
+ }
117
+ }
118
+ this.customFees.push({
119
+ feeAmount: {
120
+ amount: tokenAmount * 10 ** finalDecimals,
121
+ decimals: finalDecimals
122
+ },
123
+ feeCollectorAccountId: collectorAccountId || "",
124
+ feeTokenId,
125
+ exemptAccounts: [...exemptAccountIds],
126
+ type: CustomFeeType.FIXED_FEE
127
+ });
128
+ return this;
129
+ }
130
+ /**
131
+ * Builds the final TopicFeeConfig object.
132
+ * @returns The TopicFeeConfig containing all added custom fees and a consolidated list of unique exempt accounts.
133
+ * @throws Error if no fees have been added.
134
+ * @throws Error if more than 10 fees have been added.
135
+ */
136
+ build() {
137
+ if (this.customFees.length === 0) {
138
+ throw new Error(
139
+ "At least one fee must be added using addHbarFee/addTokenFee or created using forHbar/forToken"
140
+ );
141
+ }
142
+ if (this.customFees.length > 10) {
143
+ throw new Error("Maximum of 10 custom fees per topic allowed");
144
+ }
145
+ const allExemptAccounts = /* @__PURE__ */ new Set();
146
+ this.customFees.forEach((fee) => {
147
+ fee.exemptAccounts.forEach((account) => allExemptAccounts.add(account));
148
+ });
149
+ return {
150
+ customFees: this.customFees,
151
+ exemptAccounts: Array.from(allExemptAccounts)
152
+ };
153
+ }
154
+ }
7
155
  export {
8
- CustomFeeType
156
+ FeeConfigBuilder
9
157
  };
10
158
  //# sourceMappingURL=standards-sdk.es20.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-sdk.es20.js","sources":["../../src/fees/types.ts"],"sourcesContent":["export interface FeeConfigBuilderInterface {\n addHbarFee(\n hbarAmount: number,\n collectorAccountId?: string,\n exemptAccountIds?: string[]\n ): FeeConfigBuilderInterface;\n addTokenFee(\n tokenAmount: number,\n feeTokenId: string,\n collectorAccountId?: string,\n decimals?: number,\n exemptAccountIds?: string[]\n ): Promise<FeeConfigBuilderInterface>;\n build(): TopicFeeConfig;\n}\n\nexport enum CustomFeeType {\n FIXED_FEE = 'FIXED_FEE',\n FRACTIONAL_FEE = 'FRACTIONAL_FEE',\n ROYALTY_FEE = 'ROYALTY_FEE'\n}\n\nexport type FeeAmount = {\n amount: number;\n decimals?: number;\n};\n\nexport interface TokenFeeConfig {\n feeAmount: FeeAmount;\n feeCollectorAccountId: string;\n feeTokenId?: string;\n exemptAccounts: string[];\n type: CustomFeeType;\n}\n\nexport interface TopicFeeConfig {\n customFees: TokenFeeConfig[];\n exemptAccounts: string[];\n}\n"],"names":["CustomFeeType"],"mappings":"AAgBY,IAAA,kCAAAA,mBAAL;AACLA,iBAAA,WAAY,IAAA;AACZA,iBAAA,gBAAiB,IAAA;AACjBA,iBAAA,aAAc,IAAA;AAHJA,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;"}
1
+ {"version":3,"file":"standards-sdk.es20.js","sources":["../../src/fees/fee-config-builder.ts"],"sourcesContent":["import {\n FeeConfigBuilderInterface,\n TokenFeeConfig,\n TopicFeeConfig,\n CustomFeeType,\n} from './types';\nimport { HederaMirrorNode } from '../services/mirror-node';\nimport { Logger } from '../utils/logger';\nimport { NetworkType } from '../utils/types';\n\n/**\n * FeeConfigBuilder provides a fluent interface for creating fee configurations\n * for HCS-10 topics. This makes it easy to configure fees without dealing with\n * the complexity of the underlying fee structure.\n *\n * Example usage:\n *\n * // Super simple one-liner with the factory method\n * const simpleFeeConfig = FeeConfigBuilder.forHbar(5, '0.0.12345', NetworkType.TESTNET, new Logger(), ['0.0.67890']);\n *\n * // With multiple fees:\n * const multipleFeeConfig = new FeeConfigBuilder({\n * network: NetworkType.TESTNET,\n * logger: new Logger(),\n * defaultCollectorAccountId: '0.0.12345',\n * defaultExemptAccountIds: ['0.0.67890']\n * })\n * .withHbarFee(1) // 1 HBAR fee\n * .withTokenFee(10, '0.0.54321') // 10 units of token 0.0.54321\n * .build();\n *\n * With Agent Builder\n * const agent = new AgentBuilder()\n * .setName('Fee Collector Agent')\n * .setDescription('An agent that collects fees')\n * .setInboundTopicType(InboundTopicType.FEE_BASED)\n * .setFeeConfig(FeeConfigBuilder.forHbar(1, '0.0.12345', NetworkType.TESTNET, new Logger(), ['0.0.67890']))\n * .setNetwork('testnet')\n .build();\n\n * Directly with client\n * const client = new HCS10Client(config);\n * const connectionFeeConfig = new FeeConfigBuilder({\n * network: NetworkType.TESTNET,\n * logger: new Logger(),\n * defaultCollectorAccountId: client.getAccountAndSigner().accountId,\n * defaultExemptAccountIds: ['0.0.67890']\n * })\n * .withHbarFee(0.5) // 0.5 HBAR (simple!)\n * .build();\n\n * const result = await client.handleConnectionRequest(\n * inboundTopicId,\n * requestingAccountId,\n * connectionRequestId,\n * connectionFeeConfig\n * );\n*/\nexport interface FeeConfigBuilderOptions {\n network: NetworkType;\n logger: Logger;\n defaultCollectorAccountId?: string;\n}\n\nexport class FeeConfigBuilder implements FeeConfigBuilderInterface {\n private customFees: TokenFeeConfig[] = [];\n private mirrorNode: HederaMirrorNode;\n private logger: Logger;\n private defaultCollectorAccountId: string;\n\n constructor(options: FeeConfigBuilderOptions) {\n this.logger = options.logger;\n this.mirrorNode = new HederaMirrorNode(options.network, options.logger);\n this.defaultCollectorAccountId = options.defaultCollectorAccountId || '';\n }\n\n /**\n * Static factory method to create a FeeConfigBuilder with a single HBAR fee.\n * @param hbarAmount Amount in HBAR.\n * @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.\n * @param network Network type ('mainnet' or 'testnet').\n * @param logger Logger instance.\n * @param exemptAccounts Optional array of account IDs exempt from this fee.\n * @returns A configured FeeConfigBuilder instance.\n */\n static forHbar(\n hbarAmount: number,\n collectorAccountId: string | undefined,\n network: NetworkType,\n logger: Logger,\n exemptAccounts: string[] = []\n ): FeeConfigBuilder {\n const builder = new FeeConfigBuilder({\n network,\n logger,\n defaultCollectorAccountId: collectorAccountId,\n });\n return builder.addHbarFee(hbarAmount, collectorAccountId, exemptAccounts);\n }\n\n /**\n * Static factory method to create a FeeConfigBuilder with a single token fee.\n * Automatically fetches token decimals if not provided.\n * @param tokenAmount Amount of tokens.\n * @param feeTokenId Token ID for the fee.\n * @param collectorAccountId Optional account ID to collect the fee. If omitted or undefined, defaults to the agent's own account ID during topic creation.\n * @param network Network type ('mainnet' or 'testnet').\n * @param logger Logger instance.\n * @param exemptAccounts Optional array of account IDs exempt from this fee.\n * @param decimals Optional decimals for the token (fetched if omitted).\n * @returns A Promise resolving to a configured FeeConfigBuilder instance.\n */\n static async forToken(\n tokenAmount: number,\n feeTokenId: string,\n collectorAccountId: string | undefined,\n network: NetworkType,\n logger: Logger,\n exemptAccounts: string[] = [],\n decimals?: number\n ): Promise<FeeConfigBuilder> {\n const builder = new FeeConfigBuilder({\n network,\n logger,\n defaultCollectorAccountId: collectorAccountId,\n });\n await builder.addTokenFee(\n tokenAmount,\n feeTokenId,\n collectorAccountId,\n decimals,\n exemptAccounts\n );\n return builder;\n }\n\n /**\n * Adds an HBAR fee configuration to the builder.\n * Allows chaining multiple fee additions.\n * @param hbarAmount The amount in HBAR (e.g., 0.5).\n * @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.\n * @param exemptAccountIds Optional. Accounts specifically exempt from *this* HBAR fee.\n * @returns This FeeConfigBuilder instance for chaining.\n */\n addHbarFee(\n hbarAmount: number,\n collectorAccountId?: string,\n exemptAccountIds: string[] = []\n ): FeeConfigBuilder {\n if (hbarAmount <= 0) {\n throw new Error('HBAR amount must be greater than zero');\n }\n\n this.customFees.push({\n feeAmount: {\n amount: hbarAmount * 100_000_000,\n decimals: 0,\n },\n feeCollectorAccountId: collectorAccountId || '',\n feeTokenId: undefined,\n exemptAccounts: [...exemptAccountIds],\n type: CustomFeeType.FIXED_FEE,\n });\n\n return this;\n }\n\n /**\n * Adds a token fee configuration to the builder.\n * Allows chaining multiple fee additions.\n * Fetches token decimals automatically if not provided.\n * @param tokenAmount The amount of the specified token.\n * @param feeTokenId The ID of the token to charge the fee in.\n * @param collectorAccountId Optional. The account ID to collect this fee. If omitted, defaults to the agent's own account ID during topic creation.\n * @param decimals Optional. The number of decimals for the token. If omitted, it will be fetched from the mirror node.\n * @param exemptAccountIds Optional. Accounts specifically exempt from *this* token fee.\n * @returns A Promise resolving to this FeeConfigBuilder instance for chaining.\n */\n async addTokenFee(\n tokenAmount: number,\n feeTokenId: string,\n collectorAccountId?: string,\n decimals?: number,\n exemptAccountIds: string[] = []\n ): Promise<FeeConfigBuilder> {\n if (tokenAmount <= 0) {\n throw new Error('Token amount must be greater than zero');\n }\n if (!feeTokenId) {\n throw new Error('Fee token ID is required when adding a token fee');\n }\n\n let finalDecimals = decimals;\n if (finalDecimals === undefined) {\n try {\n const tokenInfo = await this.mirrorNode.getTokenInfo(feeTokenId);\n if (tokenInfo?.decimals) {\n finalDecimals = parseInt(tokenInfo.decimals, 10);\n this.logger.info(\n `Fetched decimals for ${feeTokenId}: ${finalDecimals}`\n );\n } else {\n this.logger.warn(\n `Could not fetch decimals for ${feeTokenId}, defaulting to 0.`\n );\n finalDecimals = 0;\n }\n } catch (error) {\n this.logger.error(\n `Error fetching decimals for ${feeTokenId}, defaulting to 0: ${error}`\n );\n finalDecimals = 0;\n }\n }\n\n this.customFees.push({\n feeAmount: {\n amount: tokenAmount * 10 ** finalDecimals,\n decimals: finalDecimals,\n },\n feeCollectorAccountId: collectorAccountId || '',\n feeTokenId: feeTokenId,\n exemptAccounts: [...exemptAccountIds],\n type: CustomFeeType.FIXED_FEE,\n });\n\n return this;\n }\n\n /**\n * Builds the final TopicFeeConfig object.\n * @returns The TopicFeeConfig containing all added custom fees and a consolidated list of unique exempt accounts.\n * @throws Error if no fees have been added.\n * @throws Error if more than 10 fees have been added.\n */\n build(): TopicFeeConfig {\n if (this.customFees.length === 0) {\n throw new Error(\n 'At least one fee must be added using addHbarFee/addTokenFee or created using forHbar/forToken'\n );\n }\n\n if (this.customFees.length > 10) {\n throw new Error('Maximum of 10 custom fees per topic allowed');\n }\n\n const allExemptAccounts = new Set<string>();\n this.customFees.forEach((fee) => {\n fee.exemptAccounts.forEach((account) => allExemptAccounts.add(account));\n });\n\n return {\n customFees: this.customFees,\n exemptAccounts: Array.from(allExemptAccounts),\n };\n }\n}\n"],"names":[],"mappings":"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"}