@layerzerolabs/common-canton 0.2.121 → 0.2.122

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 (256) hide show
  1. package/.turbo/turbo-build.log +791 -777
  2. package/.turbo/turbo-test.log +17 -51
  3. package/dist/{MFVQ6EHM.js → 22ZNNS3H.js} +3 -3
  4. package/dist/{MFVQ6EHM.js.map → 22ZNNS3H.js.map} +1 -1
  5. package/dist/{Q3RL6UXD.js → 2UWZKS5E.js} +4 -4
  6. package/dist/{Q3RL6UXD.js.map → 2UWZKS5E.js.map} +1 -1
  7. package/dist/{CAJCIAM3.js → 333Q6X6C.js} +3 -3
  8. package/dist/{CAJCIAM3.js.map → 333Q6X6C.js.map} +1 -1
  9. package/dist/{HRZTWWO4.js → 3ESWXEO3.js} +3 -3
  10. package/dist/{HRZTWWO4.js.map → 3ESWXEO3.js.map} +1 -1
  11. package/dist/{AYF4OAKH.js → 4G6A7TFX.js} +4 -4
  12. package/dist/4G6A7TFX.js.map +1 -0
  13. package/dist/{5OA7RJHH.js → 4PEF77PU.js} +3 -3
  14. package/dist/{5OA7RJHH.js.map → 4PEF77PU.js.map} +1 -1
  15. package/dist/{M5WKPPPH.js → 4SOUDUP7.js} +3 -3
  16. package/dist/{M5WKPPPH.js.map → 4SOUDUP7.js.map} +1 -1
  17. package/dist/4WZTQJXP.js +30 -0
  18. package/dist/4WZTQJXP.js.map +1 -0
  19. package/dist/{QYQWHMQM.js → 5KFMHJZB.js} +3 -3
  20. package/dist/{QYQWHMQM.js.map → 5KFMHJZB.js.map} +1 -1
  21. package/dist/7JX6NIYS.js +3 -0
  22. package/dist/7JX6NIYS.js.map +1 -0
  23. package/dist/{BL22CZFA.js → A2ZXPTGE.js} +4 -4
  24. package/dist/{BL22CZFA.js.map → A2ZXPTGE.js.map} +1 -1
  25. package/dist/{3T46OKQU.js → AVC5GQFU.js} +3 -3
  26. package/dist/{3T46OKQU.js.map → AVC5GQFU.js.map} +1 -1
  27. package/dist/{45YQNHS2.js → BHESIRKK.js} +3 -3
  28. package/dist/{45YQNHS2.js.map → BHESIRKK.js.map} +1 -1
  29. package/dist/CXQSVBVW.js +67 -0
  30. package/dist/CXQSVBVW.js.map +1 -0
  31. package/dist/{WXYN3MFC.js → CYZU3DTJ.js} +3 -3
  32. package/dist/{WXYN3MFC.js.map → CYZU3DTJ.js.map} +1 -1
  33. package/dist/{LL7Z56UN.js → D3AV6J7R.js} +3 -3
  34. package/dist/{LL7Z56UN.js.map → D3AV6J7R.js.map} +1 -1
  35. package/dist/{EWDK2D2A.js → DDAINXFD.js} +3 -3
  36. package/dist/{EWDK2D2A.js.map → DDAINXFD.js.map} +1 -1
  37. package/dist/{JSG7MGHH.js → EPHLTMJZ.js} +3 -3
  38. package/dist/{JSG7MGHH.js.map → EPHLTMJZ.js.map} +1 -1
  39. package/dist/{ZPOY5WJ2.js → FZGCL63V.js} +3 -3
  40. package/dist/{ZPOY5WJ2.js.map → FZGCL63V.js.map} +1 -1
  41. package/dist/{KBZ6YXX4.js → GHWJBJNB.js} +3 -3
  42. package/dist/{KBZ6YXX4.js.map → GHWJBJNB.js.map} +1 -1
  43. package/dist/{7GI6QGS6.js → H3BWRDYY.js} +3 -3
  44. package/dist/{7GI6QGS6.js.map → H3BWRDYY.js.map} +1 -1
  45. package/dist/{WSLU3JGO.js → HU7X7G5L.js} +3 -3
  46. package/dist/{WSLU3JGO.js.map → HU7X7G5L.js.map} +1 -1
  47. package/dist/{7IWE7Y2N.js → JA7BSC7C.js} +4 -4
  48. package/dist/{7IWE7Y2N.js.map → JA7BSC7C.js.map} +1 -1
  49. package/dist/{JXKVPYCE.js → JH2I4JGJ.js} +3 -3
  50. package/dist/{JXKVPYCE.js.map → JH2I4JGJ.js.map} +1 -1
  51. package/dist/{WHTAP4A3.js → JJKMXRP7.js} +9 -7
  52. package/dist/JJKMXRP7.js.map +1 -0
  53. package/dist/{7STDATVZ.js → JUZKQC2G.js} +3 -3
  54. package/dist/{7STDATVZ.js.map → JUZKQC2G.js.map} +1 -1
  55. package/dist/{QZJONP6W.js → KCFOSGPU.js} +3 -3
  56. package/dist/{QZJONP6W.js.map → KCFOSGPU.js.map} +1 -1
  57. package/dist/{4GYCD3G4.js → KIQAFHKC.js} +3 -3
  58. package/dist/{4GYCD3G4.js.map → KIQAFHKC.js.map} +1 -1
  59. package/dist/{FXR2Z54G.js → KJRFPBY4.js} +3 -3
  60. package/dist/{FXR2Z54G.js.map → KJRFPBY4.js.map} +1 -1
  61. package/dist/M3GPMXME.js +12 -0
  62. package/dist/M3GPMXME.js.map +1 -0
  63. package/dist/{AMLJTQWB.js → N3INXXRG.js} +3 -3
  64. package/dist/{AMLJTQWB.js.map → N3INXXRG.js.map} +1 -1
  65. package/dist/{GSEDMLUC.js → NJW7UX2A.js} +3 -3
  66. package/dist/{GSEDMLUC.js.map → NJW7UX2A.js.map} +1 -1
  67. package/dist/{KTNEUXUI.js → NRGCZ4DG.js} +5 -5
  68. package/dist/{KTNEUXUI.js.map → NRGCZ4DG.js.map} +1 -1
  69. package/dist/NRSV2VHQ.js +335 -0
  70. package/dist/NRSV2VHQ.js.map +1 -0
  71. package/dist/{DAP5XJGH.js → NX67V54F.js} +3 -3
  72. package/dist/{DAP5XJGH.js.map → NX67V54F.js.map} +1 -1
  73. package/dist/{UBHUOSK3.js → OIFJOKIO.js} +3 -3
  74. package/dist/{UBHUOSK3.js.map → OIFJOKIO.js.map} +1 -1
  75. package/dist/{NKXEPWZV.js → OO73Z5K6.js} +4 -4
  76. package/dist/{NKXEPWZV.js.map → OO73Z5K6.js.map} +1 -1
  77. package/dist/{2UKHG3HM.js → OUEL7K27.js} +3 -3
  78. package/dist/{2UKHG3HM.js.map → OUEL7K27.js.map} +1 -1
  79. package/dist/{KH7RP6Q4.js → OWXOYIMA.js} +3 -3
  80. package/dist/{KH7RP6Q4.js.map → OWXOYIMA.js.map} +1 -1
  81. package/dist/{CLAE73FR.js → OZZHAISY.js} +3 -3
  82. package/dist/{CLAE73FR.js.map → OZZHAISY.js.map} +1 -1
  83. package/dist/{IIQYRITU.js → PDIG5OUV.js} +3 -3
  84. package/dist/{IIQYRITU.js.map → PDIG5OUV.js.map} +1 -1
  85. package/dist/QAKOQQ7E.js +71 -0
  86. package/dist/QAKOQQ7E.js.map +1 -0
  87. package/dist/{NS763D57.js → QJMVWOLL.js} +3 -3
  88. package/dist/{NS763D57.js.map → QJMVWOLL.js.map} +1 -1
  89. package/dist/{KVXEYMWG.js → QNO3456Y.js} +3 -3
  90. package/dist/{KVXEYMWG.js.map → QNO3456Y.js.map} +1 -1
  91. package/dist/{TDLALQCM.js → R5PCNLRD.js} +3 -3
  92. package/dist/{TDLALQCM.js.map → R5PCNLRD.js.map} +1 -1
  93. package/dist/{K2SFNQJC.js → RHNMCG3C.js} +4 -4
  94. package/dist/{K2SFNQJC.js.map → RHNMCG3C.js.map} +1 -1
  95. package/dist/RVQWP4JU.js +76 -0
  96. package/dist/RVQWP4JU.js.map +1 -0
  97. package/dist/{73I7CBP3.js → SNDN7G42.js} +3 -3
  98. package/dist/{73I7CBP3.js.map → SNDN7G42.js.map} +1 -1
  99. package/dist/{ALC4M7WK.js → T4AL4FJH.js} +3 -3
  100. package/dist/{ALC4M7WK.js.map → T4AL4FJH.js.map} +1 -1
  101. package/dist/{5HH7PZW3.js → TZTIULG5.js} +29 -29
  102. package/dist/{5HH7PZW3.js.map → TZTIULG5.js.map} +1 -1
  103. package/dist/{5E77SJL7.js → VT3WUH5Q.js} +8 -7
  104. package/dist/VT3WUH5Q.js.map +1 -0
  105. package/dist/WKC6X2E3.js +27 -0
  106. package/dist/WKC6X2E3.js.map +1 -0
  107. package/dist/WLV6EHDB.js +60 -0
  108. package/dist/WLV6EHDB.js.map +1 -0
  109. package/dist/{HLWLB4AY.js → WUXXJWII.js} +3 -3
  110. package/dist/{HLWLB4AY.js.map → WUXXJWII.js.map} +1 -1
  111. package/dist/client/amulet.d.ts.map +1 -1
  112. package/dist/client/amulet.js +1 -1
  113. package/dist/client/canton-client.js +125 -125
  114. package/dist/client/grpc.d.ts +104 -18
  115. package/dist/client/grpc.d.ts.map +1 -1
  116. package/dist/client/grpc.js +7 -1
  117. package/dist/client/index.d.ts +5 -0
  118. package/dist/client/index.d.ts.map +1 -1
  119. package/dist/client/index.js +132 -128
  120. package/dist/client/topology/mappings.d.ts +53 -0
  121. package/dist/client/topology/mappings.d.ts.map +1 -0
  122. package/dist/client/topology/mappings.js +6 -0
  123. package/dist/client/topology/mappings.js.map +1 -0
  124. package/dist/client/topology/signing.d.ts +23 -0
  125. package/dist/client/topology/signing.d.ts.map +1 -0
  126. package/dist/client/topology/signing.js +4 -0
  127. package/dist/client/topology/signing.js.map +1 -0
  128. package/dist/client/topology/synchronizer-connectivity.d.ts +26 -0
  129. package/dist/client/topology/synchronizer-connectivity.d.ts.map +1 -0
  130. package/dist/client/topology/synchronizer-connectivity.js +4 -0
  131. package/dist/client/topology/synchronizer-connectivity.js.map +1 -0
  132. package/dist/client/topology/types.d.ts +120 -0
  133. package/dist/client/topology/types.d.ts.map +1 -0
  134. package/dist/client/topology/types.js +3 -0
  135. package/dist/client/topology/types.js.map +1 -0
  136. package/dist/client/topology/utils.d.ts +38 -0
  137. package/dist/client/topology/utils.d.ts.map +1 -0
  138. package/dist/client/topology/utils.js +6 -0
  139. package/dist/client/topology/utils.js.map +1 -0
  140. package/dist/client/utils.d.ts +17 -0
  141. package/dist/client/utils.d.ts.map +1 -1
  142. package/dist/client/utils.js +1 -1
  143. package/dist/events.js +2 -2
  144. package/dist/index.d.ts +5 -4
  145. package/dist/index.d.ts.map +1 -1
  146. package/dist/index.js +141 -136
  147. package/dist/minFee.d.ts +6 -0
  148. package/dist/minFee.d.ts.map +1 -0
  149. package/dist/minFee.js +5 -0
  150. package/dist/minFee.js.map +1 -0
  151. package/dist/open-api/apis/DefaultApi.js +123 -123
  152. package/dist/open-api/apis/index.js +123 -123
  153. package/dist/open-api/index.js +123 -123
  154. package/dist/open-api/models/Command.js +3 -3
  155. package/dist/open-api/models/Completion.js +1 -1
  156. package/dist/open-api/models/Completion1.js +1 -1
  157. package/dist/open-api/models/CompletionResponse.js +5 -5
  158. package/dist/open-api/models/CompletionResponseOneOf.js +1 -1
  159. package/dist/open-api/models/CompletionStreamResponse.js +5 -5
  160. package/dist/open-api/models/CreateUserRequest.js +7 -7
  161. package/dist/open-api/models/CumulativeFilter.js +2 -2
  162. package/dist/open-api/models/DeduplicationPeriod.js +1 -1
  163. package/dist/open-api/models/DeduplicationPeriod1.js +1 -1
  164. package/dist/open-api/models/DeduplicationPeriod2.js +2 -2
  165. package/dist/open-api/models/EventFormat.js +2 -2
  166. package/dist/open-api/models/FeaturesDescriptor.js +2 -2
  167. package/dist/open-api/models/Filters.js +2 -2
  168. package/dist/open-api/models/GetActiveContractsRequest.js +2 -2
  169. package/dist/open-api/models/GetEventsByContractIdRequest.js +2 -2
  170. package/dist/open-api/models/GetLedgerApiVersionResponse.js +3 -3
  171. package/dist/open-api/models/GetTransactionByIdRequest.js +2 -2
  172. package/dist/open-api/models/GetTransactionByOffsetRequest.js +2 -2
  173. package/dist/open-api/models/GetUpdateByIdRequest.js +2 -2
  174. package/dist/open-api/models/GetUpdateByOffsetRequest.js +2 -2
  175. package/dist/open-api/models/GetUpdatesRequest.js +2 -2
  176. package/dist/open-api/models/GrantUserRightsRequest.js +7 -7
  177. package/dist/open-api/models/GrantUserRightsResponse.js +7 -7
  178. package/dist/open-api/models/IdentifierFilter.js +2 -2
  179. package/dist/open-api/models/JsCommands.js +5 -5
  180. package/dist/open-api/models/JsExecuteSubmissionAndWaitForTransactionRequest.js +5 -5
  181. package/dist/open-api/models/JsExecuteSubmissionAndWaitRequest.js +3 -3
  182. package/dist/open-api/models/JsExecuteSubmissionRequest.js +3 -3
  183. package/dist/open-api/models/JsGetUpdateResponse.js +19 -19
  184. package/dist/open-api/models/JsGetUpdateTreesResponse.js +10 -10
  185. package/dist/open-api/models/JsGetUpdatesResponse.js +19 -19
  186. package/dist/open-api/models/JsPrepareSubmissionRequest.js +5 -5
  187. package/dist/open-api/models/JsReassignment.js +4 -4
  188. package/dist/open-api/models/JsReassignmentEvent.js +3 -3
  189. package/dist/open-api/models/JsSubmitAndWaitForReassignmentResponse.js +5 -5
  190. package/dist/open-api/models/JsSubmitAndWaitForTransactionRequest.js +8 -8
  191. package/dist/open-api/models/JsTopologyTransaction.js +7 -7
  192. package/dist/open-api/models/Kind.js +5 -5
  193. package/dist/open-api/models/ListUserRightsResponse.js +7 -7
  194. package/dist/open-api/models/Operation.js +4 -4
  195. package/dist/open-api/models/Reassignment.js +5 -5
  196. package/dist/open-api/models/Reassignment1.js +5 -5
  197. package/dist/open-api/models/RevokeUserRightsRequest.js +7 -7
  198. package/dist/open-api/models/RevokeUserRightsResponse.js +7 -7
  199. package/dist/open-api/models/Right.js +6 -6
  200. package/dist/open-api/models/SubmitAndWaitForReassignmentRequest.js +2 -2
  201. package/dist/open-api/models/TopologyEvent.js +6 -6
  202. package/dist/open-api/models/TopologyEventEvent.js +5 -5
  203. package/dist/open-api/models/TopologyTransaction.js +8 -8
  204. package/dist/open-api/models/TransactionFilter.js +2 -2
  205. package/dist/open-api/models/TransactionFormat.js +2 -2
  206. package/dist/open-api/models/Update.js +18 -18
  207. package/dist/open-api/models/Update1.js +9 -9
  208. package/dist/open-api/models/Update1OneOf1.js +6 -6
  209. package/dist/open-api/models/UpdateFormat.js +2 -2
  210. package/dist/open-api/models/UpdateOneOf1.js +6 -6
  211. package/dist/open-api/models/UpdateOneOf2.js +9 -9
  212. package/dist/open-api/models/UpdateVettedPackagesRequest.js +6 -6
  213. package/dist/open-api/models/VettedPackagesChange.js +5 -5
  214. package/dist/open-api/models/index.js +122 -122
  215. package/dist/provider.d.ts +3 -0
  216. package/dist/provider.d.ts.map +1 -1
  217. package/dist/provider.js +132 -127
  218. package/dist/refresh/index.js +2 -2
  219. package/dist/refresh/resolve.js +2 -2
  220. package/dist/sdk/index.d.ts +0 -1
  221. package/dist/sdk/index.d.ts.map +1 -1
  222. package/dist/transaction.d.ts +353 -144
  223. package/dist/transaction.d.ts.map +1 -1
  224. package/dist/transaction.js +1 -1
  225. package/dist/types.d.ts +2 -0
  226. package/dist/types.d.ts.map +1 -1
  227. package/dist/types.js +1 -1
  228. package/package.json +12 -10
  229. package/src/client/amulet.ts +5 -2
  230. package/src/client/grpc.ts +396 -39
  231. package/src/client/index.ts +20 -0
  232. package/src/client/topology/mappings.ts +152 -0
  233. package/src/client/topology/signing.ts +56 -0
  234. package/src/client/topology/synchronizer-connectivity.ts +110 -0
  235. package/src/client/topology/types.ts +133 -0
  236. package/src/client/topology/utils.ts +93 -0
  237. package/src/client/utils.ts +47 -9
  238. package/src/index.ts +5 -29
  239. package/src/minFee.ts +12 -0
  240. package/src/provider.ts +11 -3
  241. package/src/sdk/index.ts +0 -1
  242. package/src/transaction.ts +25 -4
  243. package/src/types.ts +15 -0
  244. package/test/client/amulet.test.ts +64 -0
  245. package/test/provider.test.ts +22 -0
  246. package/dist/5E77SJL7.js.map +0 -1
  247. package/dist/AYF4OAKH.js.map +0 -1
  248. package/dist/F42TZTWJ.js +0 -33
  249. package/dist/F42TZTWJ.js.map +0 -1
  250. package/dist/PQI7CWCR.js +0 -19
  251. package/dist/PQI7CWCR.js.map +0 -1
  252. package/dist/WHTAP4A3.js.map +0 -1
  253. package/dist/XE6H2SH4.js +0 -3
  254. package/dist/XE6H2SH4.js.map +0 -1
  255. package/dist/YHW7AKHX.js +0 -62
  256. package/dist/YHW7AKHX.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layerzerolabs/common-canton",
3
- "version": "0.2.121",
3
+ "version": "0.2.122",
4
4
  "private": false,
5
5
  "description": "Canton VM client and utilities",
6
6
  "license": "MIT",
@@ -28,12 +28,14 @@
28
28
  "@noble/hashes": "^1.8.0",
29
29
  "@noble/secp256k1": "1.7.1",
30
30
  "@protobuf-ts/grpc-transport": "^2.9.4",
31
+ "@protobuf-ts/runtime": "^2.11.1",
32
+ "@protobuf-ts/runtime-rpc": "^2.11.1",
31
33
  "es-toolkit": "^1.39.10",
32
34
  "zod": "4.3.5",
33
- "@layerzerolabs/common-encoding-utils": "0.2.121",
34
- "@layerzerolabs/common-error-utils": "0.2.121",
35
- "@layerzerolabs/common-chain-model": "0.2.121",
36
- "@layerzerolabs/typescript-utils": "0.2.121"
35
+ "@layerzerolabs/common-encoding-utils": "0.2.122",
36
+ "@layerzerolabs/common-chain-model": "0.2.122",
37
+ "@layerzerolabs/common-error-utils": "0.2.122",
38
+ "@layerzerolabs/typescript-utils": "0.2.122"
37
39
  },
38
40
  "devDependencies": {
39
41
  "@types/node": "^22.18.6",
@@ -42,11 +44,11 @@
42
44
  "tsup": "^8.4.0",
43
45
  "typescript": "^5.8.2",
44
46
  "vitest": "^3.2.6",
45
- "@layerzerolabs/eslint-configuration": "^0.2.121",
46
- "@layerzerolabs/tsup-configuration": "0.2.121",
47
- "@layerzerolabs/typescript-configuration": "0.2.121",
48
- "@layerzerolabs/vitest-configuration": "0.2.121",
49
- "@layerzerolabs/vm-tooling-canton": "0.2.121"
47
+ "@layerzerolabs/eslint-configuration": "^0.2.122",
48
+ "@layerzerolabs/tsup-configuration": "0.2.122",
49
+ "@layerzerolabs/vm-tooling-canton": "0.2.122",
50
+ "@layerzerolabs/vitest-configuration": "0.2.122",
51
+ "@layerzerolabs/typescript-configuration": "0.2.122"
50
52
  },
51
53
  "publishConfig": {
52
54
  "access": "public",
@@ -47,7 +47,10 @@ export const fetchAmuletContext = async (
47
47
  const later = new Date(now.getTime() + CONTEXT_PROBE_EXECUTE_BEFORE_WINDOW_MS);
48
48
 
49
49
  const response = await fetch(
50
- `${walletUrl}/api/validator/v0/scan-proxy/registry/transfer-instruction/v1/transfer-factory`,
50
+ new URL(
51
+ '/api/validator/v0/scan-proxy/registry/transfer-instruction/v1/transfer-factory',
52
+ walletUrl,
53
+ ),
51
54
  {
52
55
  method: 'POST',
53
56
  headers: {
@@ -115,7 +118,7 @@ export const injectExternalPartyAmuletRules = (
115
118
 
116
119
  /** Fetch the DSO party id from the validator scan-proxy API. */
117
120
  export const fetchDsoParty = async (walletUrl: string, token: string): Promise<string> => {
118
- const response = await fetch(`${walletUrl}/api/validator/v0/scan-proxy/dso-party-id`, {
121
+ const response = await fetch(new URL('/api/validator/v0/scan-proxy/dso-party-id', walletUrl), {
119
122
  headers: { Authorization: `Bearer ${token}` },
120
123
  });
121
124
  if (!response.ok) {
@@ -1,81 +1,438 @@
1
1
  import {
2
- BaseQuery,
3
- type DecentralizedNamespaceDefinition,
4
- Empty,
2
+ AddTransactionsRequest,
3
+ Enums_TopologyChangeOp,
4
+ GenerateTransactionsRequest,
5
+ GenerateTransactionsRequest_Proposal,
5
6
  ListDecentralizedNamespaceDefinitionRequest,
6
- StoreId,
7
+ ListNamespaceDelegationRequest,
8
+ ListPartyToKeyMappingRequest,
9
+ ListPartyToParticipantRequest,
10
+ type SignedTopologyTransaction,
7
11
  TopologyManagerReadServiceClient,
12
+ TopologyManagerWriteServiceClient,
13
+ type TopologyMapping,
8
14
  } from '@canton-network/core-ledger-proto';
9
- import { ChannelCredentials } from '@grpc/grpc-js';
10
15
  import { GrpcTransport } from '@protobuf-ts/grpc-transport';
11
16
 
12
17
  import type { TokenProvider } from '../auth/token-provider';
18
+ import { CantonError, CantonProtocolError } from '../errors';
19
+ import {
20
+ buildDecentralizedNamespaceDefinitionMapping,
21
+ buildNamespaceDelegationMapping,
22
+ buildPartyToKeyMapping,
23
+ buildPartyToParticipantMapping,
24
+ } from './topology/mappings';
25
+ import { SynchronizerConnectivityServiceClient } from './topology/synchronizer-connectivity';
26
+ import type {
27
+ CantonGrpcClientOptions,
28
+ CreateDecentralizedNamespaceDefinitionTxParams,
29
+ CreateNamespaceDelegationTxParams,
30
+ CreatePartyToKeyMappingTxParams,
31
+ CreatePartyToParticipantMappingTxParams,
32
+ DecentralizedNamespaceDefinitionState,
33
+ GeneratedTopologyTransaction,
34
+ NamespaceDelegationState,
35
+ PartyToKeyMappingState,
36
+ PartyToParticipantMappingState,
37
+ UpdateDecentralizedNamespaceDefinitionTxParams,
38
+ } from './topology/types';
39
+ import {
40
+ buildChannelCredentials,
41
+ computeDecentralizedNamespace,
42
+ headStateBaseQuery,
43
+ synchronizerStore,
44
+ } from './topology/utils';
45
+ import { computePublicKeyFingerprint } from './utils';
13
46
 
14
- export type TlsOptions = {
15
- rootCert?: Buffer;
16
- clientKey?: Buffer;
17
- clientCert?: Buffer;
18
- };
19
-
20
- export type CantonGrpcClientOptions = {
21
- host: string;
22
- tokenProvider?: TokenProvider;
23
- tls?: TlsOptions;
24
- };
25
-
26
- function buildChannelCredentials(tls?: TlsOptions): ChannelCredentials {
27
- if (!tls) return ChannelCredentials.createInsecure();
28
- return ChannelCredentials.createSsl(tls.rootCert, tls.clientKey, tls.clientCert);
29
- }
47
+ /** Default gRPC client options: 128 MiB message-size limits for large admin responses. */
48
+ const DEFAULT_GRPC_CLIENT_OPTIONS = {
49
+ 'grpc.max_receive_message_length': 128 * 1024 * 1024,
50
+ 'grpc.max_send_message_length': 128 * 1024 * 1024,
51
+ } as const;
30
52
 
31
53
  /**
32
- * gRPC client for the Canton Admin API.
54
+ * gRPC client for the Canton participant admin Topology Manager API.
33
55
  *
34
- * Wraps the Topology Manager Read Service for querying topology state
35
- * (decentralized namespace definitions, etc.) via the participant's admin endpoint.
56
+ * Exposes read queries for topology mappings and write helpers that call
57
+ * `GenerateTransactions` to produce unsigned topology transactions and
58
+ * `AddTransactions` to submit signed ones.
36
59
  *
37
- * If a {@link TokenProvider} is supplied, a fresh Bearer token is acquired
38
- * before each RPC call via per-call metadata.
60
+ * A fresh Bearer token is attached to each RPC via {@link TokenProvider}.
39
61
  */
40
62
  export class CantonGrpcClient {
41
63
  readonly #transport: GrpcTransport;
42
64
  readonly #topologyRead: TopologyManagerReadServiceClient;
43
- readonly #tokenProvider?: TokenProvider;
65
+ readonly #topologyWrite: TopologyManagerWriteServiceClient;
66
+ readonly #connectivity: SynchronizerConnectivityServiceClient;
67
+ readonly #tokenProvider: TokenProvider;
68
+ #synchronizerId?: string;
44
69
 
70
+ /**
71
+ * @param opts - Admin API host, auth, optional synchronizer id, and optional TLS.
72
+ */
45
73
  constructor(opts: CantonGrpcClientOptions) {
74
+ this.#tokenProvider = opts.tokenProvider;
75
+ this.#synchronizerId = opts.synchronizerId;
46
76
  this.#transport = new GrpcTransport({
47
77
  host: opts.host,
48
- channelCredentials: buildChannelCredentials(opts.tls),
78
+ channelCredentials: buildChannelCredentials(opts.host, opts.tls),
79
+ clientOptions: opts.grpcClientOptions ?? DEFAULT_GRPC_CLIENT_OPTIONS,
49
80
  });
50
81
  this.#topologyRead = new TopologyManagerReadServiceClient(this.#transport);
51
- this.#tokenProvider = opts.tokenProvider;
82
+ this.#topologyWrite = new TopologyManagerWriteServiceClient(this.#transport);
83
+ this.#connectivity = new SynchronizerConnectivityServiceClient(this.#transport);
52
84
  }
53
85
 
86
+ /** Returns per-RPC gRPC metadata with a fresh Bearer token. */
54
87
  async #getMeta(): Promise<Record<string, string>> {
55
- if (!this.#tokenProvider) return {};
56
88
  const token = await this.#tokenProvider.getToken();
57
89
  return { Authorization: `Bearer ${token}` };
58
90
  }
59
91
 
60
- async getLatestDecentralizedNamespaceDefinition(
92
+ /**
93
+ * Returns the client synchronizer id, discovering it on first use when omitted at construction.
94
+ *
95
+ * @throws {CantonProtocolError} If the participant exposes no synchronizer store.
96
+ */
97
+ async #getSynchronizerId(): Promise<string> {
98
+ if (this.#synchronizerId) {
99
+ return this.#synchronizerId;
100
+ }
101
+ this.#synchronizerId = await this.#discoverSynchronizerId();
102
+ return this.#synchronizerId;
103
+ }
104
+
105
+ /**
106
+ * Resolves the logical id of the first synchronizer the participant is connected to.
107
+ *
108
+ * @throws {CantonProtocolError} If the participant is not connected to any synchronizer.
109
+ */
110
+ async #discoverSynchronizerId(): Promise<string> {
111
+ const { response } = await this.#connectivity.listConnectedSynchronizers(
112
+ {},
113
+ { meta: await this.#getMeta() },
114
+ );
115
+ for (const synchronizer of response.connectedSynchronizers) {
116
+ if (synchronizer.synchronizerId) {
117
+ return synchronizer.synchronizerId;
118
+ }
119
+ }
120
+ throw new CantonProtocolError('Participant is not connected to any synchronizer');
121
+ }
122
+
123
+ /**
124
+ * Calls `GenerateTransactions` for a single ADD_REPLACE mapping.
125
+ *
126
+ * @param synchronizerId - Synchronizer store to target.
127
+ * @param mapping - Topology mapping to encode into the transaction.
128
+ * @param serial - Topology serial (`0` lets Canton auto-determine).
129
+ * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).
130
+ * @throws {CantonProtocolError} If the RPC returns no generated transaction.
131
+ */
132
+ async #generateTopologyTransaction(
61
133
  synchronizerId: string,
134
+ mapping: TopologyMapping,
135
+ serial: number,
136
+ ): Promise<GeneratedTopologyTransaction> {
137
+ const { response } = await this.#topologyWrite.generateTransactions(
138
+ GenerateTransactionsRequest.create({
139
+ proposals: [
140
+ GenerateTransactionsRequest_Proposal.create({
141
+ operation: Enums_TopologyChangeOp.ADD_REPLACE,
142
+ serial,
143
+ mapping,
144
+ store: synchronizerStore(synchronizerId),
145
+ }),
146
+ ],
147
+ }),
148
+ { meta: await this.#getMeta() },
149
+ );
150
+
151
+ const generated = response.generatedTransactions[0];
152
+ if (!generated) {
153
+ throw new CantonProtocolError('GenerateTransactions returned no topology transaction');
154
+ }
155
+ return generated;
156
+ }
157
+
158
+ /**
159
+ * Lists Namespace Delegation (NSD) mappings for a namespace.
160
+ *
161
+ * Queries topology head state on the synchronizer. Returns every result from
162
+ * the list RPC.
163
+ *
164
+ * @param namespaceFingerprint - Namespace to filter on (for root NSD, the owner key fingerprint).
165
+ * @returns All matching NSD mappings, or an empty array if none exist.
166
+ */
167
+ async getNamespaceDelegation(
168
+ namespaceFingerprint: string,
169
+ ): Promise<NamespaceDelegationState[]> {
170
+ const synchronizerId = await this.#getSynchronizerId();
171
+ const { response } = await this.#topologyRead.listNamespaceDelegation(
172
+ ListNamespaceDelegationRequest.create({
173
+ baseQuery: headStateBaseQuery(synchronizerId),
174
+ filterNamespace: namespaceFingerprint,
175
+ // Empty string = no target-key filter; return all delegations for this namespace.
176
+ filterTargetKeyFingerprint: '',
177
+ }),
178
+ { meta: await this.#getMeta() },
179
+ );
180
+
181
+ return response.results.flatMap((result) => {
182
+ const item = result.item;
183
+ const publicKey = item?.targetKey?.publicKey;
184
+ if (!item || !publicKey) {
185
+ return [];
186
+ }
187
+ return [
188
+ {
189
+ namespace: item.namespace,
190
+ targetKeyFingerprint: computePublicKeyFingerprint(publicKey),
191
+ isRootDelegation: item.isRootDelegation,
192
+ serial: result.context?.serial ?? 0,
193
+ },
194
+ ];
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Lists Decentralized Namespace Definition (DND) mappings for a namespace.
200
+ *
201
+ * Queries topology head state on the synchronizer. For a party id `hint::1220…`,
202
+ * pass the `1220…` suffix as `namespaceFingerprint`.
203
+ *
204
+ * @param namespaceFingerprint - Decentralized namespace fingerprint to filter on.
205
+ * @returns All matching DND mappings, or an empty array if none exist.
206
+ */
207
+ async getDecentralizedNamespaceDefinition(
62
208
  namespaceFingerprint: string,
63
- ): Promise<DecentralizedNamespaceDefinition | undefined> {
209
+ ): Promise<DecentralizedNamespaceDefinitionState[]> {
210
+ const synchronizerId = await this.#getSynchronizerId();
64
211
  const { response } = await this.#topologyRead.listDecentralizedNamespaceDefinition(
65
212
  ListDecentralizedNamespaceDefinitionRequest.create({
66
- baseQuery: BaseQuery.create({
67
- store: StoreId.create({
68
- store: { oneofKind: 'synchronizer', synchronizer: { id: synchronizerId } },
69
- }),
70
- timeQuery: { oneofKind: 'headState', headState: Empty.create({}) },
71
- }),
213
+ baseQuery: headStateBaseQuery(synchronizerId),
72
214
  filterNamespace: namespaceFingerprint,
73
215
  }),
74
216
  { meta: await this.#getMeta() },
75
217
  );
76
- return response.results[0]?.item;
218
+
219
+ return response.results.flatMap((result) => {
220
+ const item = result.item;
221
+ if (!item) {
222
+ return [];
223
+ }
224
+ return [
225
+ {
226
+ namespace: item.decentralizedNamespace,
227
+ threshold: item.threshold,
228
+ owners: [...item.owners],
229
+ serial: result.context?.serial ?? 0,
230
+ },
231
+ ];
232
+ });
233
+ }
234
+
235
+ /**
236
+ * Lists Party-to-Key (PTK) mappings for a party.
237
+ *
238
+ * Queries topology head state on the synchronizer.
239
+ *
240
+ * @param partyId - Full party identifier (e.g. `hint::1220…`).
241
+ * @returns All matching PTK mappings, or an empty array if none exist.
242
+ */
243
+ async getPartyToKeyMapping(partyId: string): Promise<PartyToKeyMappingState[]> {
244
+ const synchronizerId = await this.#getSynchronizerId();
245
+ const { response } = await this.#topologyRead.listPartyToKeyMapping(
246
+ ListPartyToKeyMappingRequest.create({
247
+ baseQuery: headStateBaseQuery(synchronizerId),
248
+ filterParty: partyId,
249
+ }),
250
+ { meta: await this.#getMeta() },
251
+ );
252
+
253
+ return response.results.flatMap((result) => {
254
+ const item = result.item;
255
+ if (!item) {
256
+ return [];
257
+ }
258
+ return [
259
+ {
260
+ party: item.party,
261
+ threshold: item.threshold,
262
+ signingKeyFingerprints: item.signingKeys.map((key) =>
263
+ computePublicKeyFingerprint(key.publicKey),
264
+ ),
265
+ serial: result.context?.serial ?? 0,
266
+ },
267
+ ];
268
+ });
269
+ }
270
+
271
+ /**
272
+ * Lists Party-to-Participant (PTP) mappings for a party.
273
+ *
274
+ * Queries topology head state on the synchronizer.
275
+ *
276
+ * @param partyId - Full party identifier (e.g. `hint::1220…`).
277
+ * @param proposals - If `true`, query pending proposals instead of authorized mappings.
278
+ * @returns All matching PTP mappings, or an empty array if none exist.
279
+ */
280
+ async getPartyToParticipantMapping(
281
+ partyId: string,
282
+ proposals = false,
283
+ ): Promise<PartyToParticipantMappingState[]> {
284
+ const synchronizerId = await this.#getSynchronizerId();
285
+ const { response } = await this.#topologyRead.listPartyToParticipant(
286
+ ListPartyToParticipantRequest.create({
287
+ baseQuery: headStateBaseQuery(synchronizerId, proposals),
288
+ filterParty: partyId,
289
+ // Empty string = no participant filter; return all hosting mappings for this party.
290
+ filterParticipant: '',
291
+ }),
292
+ { meta: await this.#getMeta() },
293
+ );
294
+
295
+ return response.results.flatMap((result) => {
296
+ const item = result.item;
297
+ if (!item) {
298
+ return [];
299
+ }
300
+ return [
301
+ {
302
+ party: item.party,
303
+ threshold: item.threshold,
304
+ participants: item.participants.map((participant) => ({
305
+ participantUid: participant.participantUid,
306
+ permission: participant.permission,
307
+ })),
308
+ serial: result.context?.serial ?? 0,
309
+ },
310
+ ];
311
+ });
312
+ }
313
+
314
+ /**
315
+ * Builds an unsigned Namespace Delegation (NSD) topology transaction.
316
+ *
317
+ * Calls `GenerateTransactions` with an ADD_REPLACE mapping. The returned
318
+ * `transactionHash` must be signed by the namespace key.
319
+ *
320
+ * @param params - Owner public key and optional serial.
321
+ * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).
322
+ */
323
+ async createNamespaceDelegationTx(
324
+ params: CreateNamespaceDelegationTxParams,
325
+ ): Promise<GeneratedTopologyTransaction> {
326
+ const synchronizerId = await this.#getSynchronizerId();
327
+ const mapping = buildNamespaceDelegationMapping(params.publicKeyDer);
328
+ return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);
329
+ }
330
+
331
+ /**
332
+ * Builds an unsigned Decentralized Namespace Definition (DND) topology transaction.
333
+ *
334
+ * The decentralized namespace id is derived from `params.owners`. All owners
335
+ * must sign the transaction hash.
336
+ *
337
+ * @param params - Owner fingerprints, threshold, and optional serial.
338
+ * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).
339
+ */
340
+ async createDecentralizedNamespaceDefinitionTx(
341
+ params: CreateDecentralizedNamespaceDefinitionTxParams,
342
+ ): Promise<GeneratedTopologyTransaction> {
343
+ const synchronizerId = await this.#getSynchronizerId();
344
+ const decentralizedNamespace = computeDecentralizedNamespace(params.owners);
345
+ const mapping = buildDecentralizedNamespaceDefinitionMapping(
346
+ decentralizedNamespace,
347
+ params.threshold,
348
+ params.owners,
349
+ );
350
+ return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);
351
+ }
352
+
353
+ async updateDecentralizedNamespaceDefinitionTx(
354
+ params: UpdateDecentralizedNamespaceDefinitionTxParams,
355
+ ): Promise<GeneratedTopologyTransaction> {
356
+ const synchronizerId = await this.#getSynchronizerId();
357
+ const mapping = buildDecentralizedNamespaceDefinitionMapping(
358
+ params.namespace,
359
+ params.threshold,
360
+ params.owners,
361
+ );
362
+ return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);
363
+ }
364
+
365
+ /**
366
+ * Builds an unsigned Party-to-Key (PTK) topology transaction.
367
+ *
368
+ * Decentralized namespace owners must sign the transaction hash.
369
+ *
370
+ * @param params - Party id, signing keys, threshold, and optional serial.
371
+ * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).
372
+ */
373
+ async createPartyToKeyTx(
374
+ params: CreatePartyToKeyMappingTxParams,
375
+ ): Promise<GeneratedTopologyTransaction> {
376
+ const synchronizerId = await this.#getSynchronizerId();
377
+ const mapping = buildPartyToKeyMapping(
378
+ params.partyId,
379
+ params.signingPublicKeyDers,
380
+ params.threshold,
381
+ );
382
+ return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);
383
+ }
384
+
385
+ /**
386
+ * Builds an unsigned Party-to-Participant (PTP) topology transaction.
387
+ *
388
+ * Party owners sign the transaction hash. On submit, set `proposal: true` on the
389
+ * signed transaction so the hosting participant can authorize via `Authorize`.
390
+ *
391
+ * @param params - Party id, participant ids, threshold, and optional serial.
392
+ * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).
393
+ */
394
+ async createPartyToParticipantTx(
395
+ params: CreatePartyToParticipantMappingTxParams,
396
+ ): Promise<GeneratedTopologyTransaction> {
397
+ const synchronizerId = await this.#getSynchronizerId();
398
+ const mapping = buildPartyToParticipantMapping(
399
+ params.partyId,
400
+ params.participantIds,
401
+ params.threshold,
402
+ );
403
+ return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);
404
+ }
405
+
406
+ /**
407
+ * Submits signed topology transactions to the synchronizer store.
408
+ *
409
+ * Multiple transactions are submitted atomically in one `AddTransactions` call.
410
+ * When batching, sign `computeMultiTransactionHash` over all transaction hashes
411
+ * and attach the same `MultiTransactionSignatures` to each entry.
412
+ *
413
+ * Set `proposal: true` on a transaction when the hosting participant must
414
+ * authorize that mapping afterward.
415
+ *
416
+ * @param transactions - One or more signed topology transactions.
417
+ * @throws {CantonError} If `transactions` is empty.
418
+ */
419
+ async submitTopologyTransactions(
420
+ transactions: readonly SignedTopologyTransaction[],
421
+ ): Promise<void> {
422
+ if (transactions.length === 0) {
423
+ throw new CantonError('AddTransactions requires at least one transaction');
424
+ }
425
+ const synchronizerId = await this.#getSynchronizerId();
426
+ await this.#topologyWrite.addTransactions(
427
+ AddTransactionsRequest.create({
428
+ transactions: [...transactions],
429
+ store: synchronizerStore(synchronizerId),
430
+ }),
431
+ { meta: await this.#getMeta() },
432
+ );
77
433
  }
78
434
 
435
+ /** Closes the underlying gRPC transport. */
79
436
  close(): void {
80
437
  this.#transport.close();
81
438
  }
@@ -3,3 +3,23 @@ export { CantonClient } from './canton-client';
3
3
  export * from './grpc';
4
4
  export * from './interface';
5
5
  export * from './utils';
6
+
7
+ // Topology Manager API
8
+ export type { TopologySignature } from './topology/signing';
9
+ export { buildMultiTransactionSignatures, buildSignedTransaction } from './topology/signing';
10
+ export type {
11
+ CantonGrpcClientOptions,
12
+ CreateDecentralizedNamespaceDefinitionTxParams,
13
+ CreateNamespaceDelegationTxParams,
14
+ CreatePartyToKeyMappingTxParams,
15
+ CreatePartyToParticipantMappingTxParams,
16
+ DecentralizedNamespaceDefinitionState,
17
+ GeneratedTopologyTransaction,
18
+ NamespaceDelegationState,
19
+ PartyToKeyMappingState,
20
+ PartyToParticipantMappingState,
21
+ TlsOptions,
22
+ UpdateDecentralizedNamespaceDefinitionTxParams,
23
+ } from './topology/types';
24
+ export { computeDecentralizedNamespace, computeMultiTransactionHash } from './topology/utils';
25
+ export type { SignedTopologyTransaction } from '@canton-network/core-ledger-proto';