@layerzerolabs/common-canton 1.2.35 → 1.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AH32N3GF.js → 262S47C4.js} +6 -5
- package/dist/262S47C4.js.map +1 -0
- package/dist/{WAKNWPCR.js → 5AD6IR4R.js} +10 -7
- package/dist/5AD6IR4R.js.map +1 -0
- package/dist/{IA2UQ4WQ.js → BFQYTMKD.js} +5 -5
- package/dist/BFQYTMKD.js.map +1 -0
- package/dist/{SEPKIDEX.js → D52OIJDY.js} +2 -2
- package/dist/{SEPKIDEX.js.map → D52OIJDY.js.map} +1 -1
- package/dist/{ZZCNITRN.js → FFZGONTK.js} +3 -3
- package/dist/{ZZCNITRN.js.map → FFZGONTK.js.map} +1 -1
- package/dist/{QAKOQQ7E.js → PL4H5XEA.js} +19 -8
- package/dist/PL4H5XEA.js.map +1 -0
- package/dist/client/canton-client.d.ts +4 -0
- package/dist/client/canton-client.d.ts.map +1 -1
- package/dist/client/canton-client.js +1 -1
- package/dist/client/grpc.d.ts +1 -1
- package/dist/client/grpc.d.ts.map +1 -1
- package/dist/client/grpc.js +2 -2
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client/interface.d.ts +2 -0
- package/dist/client/interface.d.ts.map +1 -1
- package/dist/client/topology/types.d.ts +2 -11
- package/dist/client/topology/types.d.ts.map +1 -1
- package/dist/client/topology/utils.d.ts +4 -4
- package/dist/client/topology/utils.d.ts.map +1 -1
- package/dist/client/topology/utils.js +2 -1
- package/dist/index.js +8 -8
- package/dist/provider.d.ts +3 -2
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +4 -4
- package/dist/refresh/index.js +2 -2
- package/dist/refresh/resolve.js +2 -2
- package/dist/sdk/canton-sdk.d.ts +1 -0
- package/dist/sdk/canton-sdk.d.ts.map +1 -1
- package/dist/sdk/canton-sdk.js +1 -1
- package/dist/sdk/index.js +1 -1
- package/package.json +10 -10
- package/src/client/canton-client.ts +16 -6
- package/src/client/grpc.ts +4 -2
- package/src/client/index.ts +0 -1
- package/src/client/interface.ts +2 -2
- package/src/client/topology/types.ts +2 -12
- package/src/client/topology/utils.ts +31 -10
- package/src/provider.ts +4 -2
- package/src/sdk/canton-sdk.ts +1 -1
- package/test/client/topology/utils.test.ts +47 -0
- package/test/provider.test.ts +37 -2
- package/dist/AH32N3GF.js.map +0 -1
- package/dist/IA2UQ4WQ.js.map +0 -1
- package/dist/QAKOQQ7E.js.map +0 -1
- package/dist/WAKNWPCR.js.map +0 -1
|
@@ -1003,14 +1003,16 @@ export class CantonClient implements ICantonClient {
|
|
|
1003
1003
|
* @param offset - Ledger offset for the snapshot
|
|
1004
1004
|
* @param opts.templateIds - Optional template IDs to filter by
|
|
1005
1005
|
* @param opts.limit - Maximum number of contracts to return
|
|
1006
|
+
* @param opts.includeCreatedEventBlob - Include CIP disclosure blobs (default false)
|
|
1006
1007
|
*/
|
|
1007
1008
|
async queryActiveContracts(
|
|
1008
1009
|
party: string,
|
|
1009
1010
|
offset: number,
|
|
1010
|
-
opts?: { templateIds?: string[]; limit?: number },
|
|
1011
|
+
opts?: { templateIds?: string[]; limit?: number; includeCreatedEventBlob?: boolean },
|
|
1011
1012
|
): Promise<JsActiveContract[]> {
|
|
1012
1013
|
return this.queryActiveContractsByParties([party], offset, opts?.templateIds ?? [], {
|
|
1013
1014
|
limit: opts?.limit,
|
|
1015
|
+
includeCreatedEventBlob: opts?.includeCreatedEventBlob,
|
|
1014
1016
|
});
|
|
1015
1017
|
}
|
|
1016
1018
|
|
|
@@ -1023,17 +1025,18 @@ export class CantonClient implements ICantonClient {
|
|
|
1023
1025
|
* @param offset - Ledger offset for the snapshot
|
|
1024
1026
|
* @param templateIds - Template IDs to filter by
|
|
1025
1027
|
* @param opts.limit - Maximum number of contracts to return
|
|
1028
|
+
* @param opts.includeCreatedEventBlob - Include CIP disclosure blobs (default false)
|
|
1026
1029
|
*/
|
|
1027
1030
|
async queryActiveContractsByParties(
|
|
1028
1031
|
parties: string[],
|
|
1029
1032
|
offset: number,
|
|
1030
1033
|
templateIds: string[],
|
|
1031
|
-
opts?: { limit?: number },
|
|
1034
|
+
opts?: { limit?: number; includeCreatedEventBlob?: boolean },
|
|
1032
1035
|
): Promise<JsActiveContract[]> {
|
|
1033
1036
|
return this.#fetchActiveContracts(
|
|
1034
1037
|
parties,
|
|
1035
1038
|
offset,
|
|
1036
|
-
this.#buildCumulativeFilters(templateIds),
|
|
1039
|
+
this.#buildCumulativeFilters(templateIds, opts?.includeCreatedEventBlob),
|
|
1037
1040
|
opts,
|
|
1038
1041
|
);
|
|
1039
1042
|
}
|
|
@@ -1147,16 +1150,23 @@ export class CantonClient implements ICantonClient {
|
|
|
1147
1150
|
* Build cumulative filters for party-based queries.
|
|
1148
1151
|
* If templateIds provided, filters by those templates; otherwise uses wildcard.
|
|
1149
1152
|
*/
|
|
1150
|
-
#buildCumulativeFilters(
|
|
1153
|
+
#buildCumulativeFilters(
|
|
1154
|
+
templateIds?: string[],
|
|
1155
|
+
includeCreatedEventBlob = false,
|
|
1156
|
+
): CumulativeFilter[] {
|
|
1151
1157
|
if (templateIds?.length) {
|
|
1152
1158
|
return templateIds.map((templateId) => ({
|
|
1153
1159
|
identifierFilter: {
|
|
1154
|
-
templateFilter: { value: { templateId, includeCreatedEventBlob
|
|
1160
|
+
templateFilter: { value: { templateId, includeCreatedEventBlob } },
|
|
1155
1161
|
},
|
|
1156
1162
|
}));
|
|
1157
1163
|
}
|
|
1158
1164
|
return [
|
|
1159
|
-
{
|
|
1165
|
+
{
|
|
1166
|
+
identifierFilter: {
|
|
1167
|
+
wildcardFilter: { value: { includeCreatedEventBlob } },
|
|
1168
|
+
},
|
|
1169
|
+
},
|
|
1160
1170
|
];
|
|
1161
1171
|
}
|
|
1162
1172
|
|
package/src/client/grpc.ts
CHANGED
|
@@ -68,14 +68,14 @@ export class CantonGrpcClient {
|
|
|
68
68
|
#synchronizerId?: string;
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
* @param opts - Admin API host, auth, optional synchronizer id, and
|
|
71
|
+
* @param opts - Admin API host, auth, optional synchronizer id, and transport security.
|
|
72
72
|
*/
|
|
73
73
|
constructor(opts: CantonGrpcClientOptions) {
|
|
74
74
|
this.#tokenProvider = opts.tokenProvider;
|
|
75
75
|
this.#synchronizerId = opts.synchronizerId;
|
|
76
76
|
this.#transport = new GrpcTransport({
|
|
77
77
|
host: opts.host,
|
|
78
|
-
channelCredentials: buildChannelCredentials(opts.host, opts.
|
|
78
|
+
channelCredentials: buildChannelCredentials(opts.host, opts.insecureTransport),
|
|
79
79
|
clientOptions: opts.grpcClientOptions ?? DEFAULT_GRPC_CLIENT_OPTIONS,
|
|
80
80
|
});
|
|
81
81
|
this.#topologyRead = new TopologyManagerReadServiceClient(this.#transport);
|
|
@@ -149,9 +149,11 @@ export class CantonGrpcClient {
|
|
|
149
149
|
);
|
|
150
150
|
|
|
151
151
|
const generated = response.generatedTransactions[0];
|
|
152
|
+
|
|
152
153
|
if (!generated) {
|
|
153
154
|
throw new CantonProtocolError('GenerateTransactions returned no topology transaction');
|
|
154
155
|
}
|
|
156
|
+
|
|
155
157
|
return generated;
|
|
156
158
|
}
|
|
157
159
|
|
package/src/client/index.ts
CHANGED
|
@@ -18,7 +18,6 @@ export type {
|
|
|
18
18
|
NamespaceDelegationState,
|
|
19
19
|
PartyToKeyMappingState,
|
|
20
20
|
PartyToParticipantMappingState,
|
|
21
|
-
TlsOptions,
|
|
22
21
|
UpdateDecentralizedNamespaceDefinitionTxParams,
|
|
23
22
|
} from './topology/types';
|
|
24
23
|
export { computeDecentralizedNamespace, computeMultiTransactionHash } from './topology/utils';
|
package/src/client/interface.ts
CHANGED
|
@@ -306,7 +306,7 @@ export interface ICantonClient {
|
|
|
306
306
|
queryActiveContracts(
|
|
307
307
|
party: string,
|
|
308
308
|
offset: number,
|
|
309
|
-
opts?: { templateIds?: string[]; limit?: number },
|
|
309
|
+
opts?: { templateIds?: string[]; limit?: number; includeCreatedEventBlob?: boolean },
|
|
310
310
|
): Promise<JsActiveContract[]>;
|
|
311
311
|
|
|
312
312
|
/**
|
|
@@ -322,7 +322,7 @@ export interface ICantonClient {
|
|
|
322
322
|
parties: string[],
|
|
323
323
|
offset: number,
|
|
324
324
|
templateIds: string[],
|
|
325
|
-
opts?: { limit?: number },
|
|
325
|
+
opts?: { limit?: number; includeCreatedEventBlob?: boolean },
|
|
326
326
|
): Promise<JsActiveContract[]>;
|
|
327
327
|
|
|
328
328
|
/**
|
|
@@ -104,16 +104,6 @@ export type PartyToParticipantMappingState = {
|
|
|
104
104
|
serial: number;
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
-
/** TLS credentials for Canton admin gRPC connections. */
|
|
108
|
-
export type TlsOptions = {
|
|
109
|
-
/** CA root certificate for server verification. */
|
|
110
|
-
rootCert?: Buffer;
|
|
111
|
-
/** Client private key for mutual TLS. */
|
|
112
|
-
clientKey?: Buffer;
|
|
113
|
-
/** Client certificate for mutual TLS. */
|
|
114
|
-
clientCert?: Buffer;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
107
|
/** Options for constructing a {@link CantonGrpcClient}. */
|
|
118
108
|
export type CantonGrpcClientOptions = {
|
|
119
109
|
/** Participant admin API host (e.g. `participant.example.com:443`). */
|
|
@@ -126,8 +116,8 @@ export type CantonGrpcClientOptions = {
|
|
|
126
116
|
* is resolved on the first RPC.
|
|
127
117
|
*/
|
|
128
118
|
synchronizerId?: string;
|
|
129
|
-
/**
|
|
130
|
-
|
|
119
|
+
/** Drops transport encryption; loopback hosts only. Defaults to TLS. */
|
|
120
|
+
insecureTransport?: boolean;
|
|
131
121
|
/** Overrides the default gRPC channel options. */
|
|
132
122
|
grpcClientOptions?: ClientOptions;
|
|
133
123
|
};
|
|
@@ -3,8 +3,8 @@ import { ChannelCredentials } from '@grpc/grpc-js';
|
|
|
3
3
|
|
|
4
4
|
import { bytesToHex } from '@layerzerolabs/common-encoding-utils';
|
|
5
5
|
|
|
6
|
+
import { CantonError } from '../../errors';
|
|
6
7
|
import { cantonMultihash } from '../utils';
|
|
7
|
-
import type { TlsOptions } from './types';
|
|
8
8
|
|
|
9
9
|
/** Canton hash purpose for decentralized namespace derivation. */
|
|
10
10
|
const HASH_PURPOSE_DECENTRALIZED_NAMESPACE = 37;
|
|
@@ -77,17 +77,38 @@ export function headStateBaseQuery(synchronizerId: string, proposals = false): B
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost', '::1']);
|
|
81
|
+
const LOOPBACK_IPV4 = /^127(\.\d{1,3}){3}$/;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Whether a `host:port` target addresses the local machine.
|
|
85
|
+
*/
|
|
86
|
+
const isLoopbackHost = (host: string): boolean => {
|
|
87
|
+
const hostname = host
|
|
88
|
+
.replace(/:\d+$/, '')
|
|
89
|
+
.replace(/^\[(.*)\]$/, '$1')
|
|
90
|
+
.toLowerCase();
|
|
91
|
+
return LOOPBACK_HOSTNAMES.has(hostname) || LOOPBACK_IPV4.test(hostname);
|
|
92
|
+
};
|
|
93
|
+
|
|
80
94
|
/**
|
|
81
95
|
* Builds gRPC channel credentials for the Canton admin API.
|
|
82
96
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
97
|
+
* Encrypted whatever the port, because every admin call carries a reusable bearer token.
|
|
98
|
+
*
|
|
99
|
+
* @throws {CantonError} If an unencrypted channel is asked for on a remote host.
|
|
85
100
|
*/
|
|
86
|
-
export
|
|
87
|
-
|
|
88
|
-
|
|
101
|
+
export const buildChannelCredentials = (
|
|
102
|
+
host: string,
|
|
103
|
+
insecureTransport = false,
|
|
104
|
+
): ChannelCredentials => {
|
|
105
|
+
if (!insecureTransport) {
|
|
106
|
+
return ChannelCredentials.createSsl();
|
|
107
|
+
} else if (!isLoopbackHost(host)) {
|
|
108
|
+
throw new CantonError(
|
|
109
|
+
`Canton admin API requires an encrypted channel for a remote host: ${host}`,
|
|
110
|
+
);
|
|
89
111
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
112
|
+
|
|
113
|
+
return ChannelCredentials.createInsecure();
|
|
114
|
+
};
|
package/src/provider.ts
CHANGED
|
@@ -137,9 +137,10 @@ export type CreateCantonChainProviderOptions = {
|
|
|
137
137
|
/**
|
|
138
138
|
* Create a {@link CantonChainProvider} from a provider URI.
|
|
139
139
|
*
|
|
140
|
-
* - **isLocal=true**: Uses {@link LocalTokenProvider} with admin-level access (self-signed JWTs)
|
|
140
|
+
* - **isLocal=true**: Uses {@link LocalTokenProvider} with admin-level access (self-signed JWTs)
|
|
141
|
+
* over an unencrypted admin channel, allowed for a loopback admin host only.
|
|
141
142
|
* - **isLocal=false**: Uses {@link ClientCredentialsTokenProvider} with OAuth2 client
|
|
142
|
-
* credentials extracted from the URI query parameters.
|
|
143
|
+
* credentials extracted from the URI query parameters, over a TLS admin channel.
|
|
143
144
|
*/
|
|
144
145
|
export function createCantonChainProvider({
|
|
145
146
|
uri,
|
|
@@ -163,6 +164,7 @@ export function createCantonChainProvider({
|
|
|
163
164
|
const grpcClient = new CantonGrpcClient({
|
|
164
165
|
host: params.adminApiHost,
|
|
165
166
|
tokenProvider,
|
|
167
|
+
insecureTransport: isLocal,
|
|
166
168
|
});
|
|
167
169
|
|
|
168
170
|
return {
|
package/src/sdk/canton-sdk.ts
CHANGED
|
@@ -421,7 +421,7 @@ export class CantonSdk {
|
|
|
421
421
|
queryActiveContracts(
|
|
422
422
|
party: string,
|
|
423
423
|
offset: number,
|
|
424
|
-
opts?: { templateIds?: string[]; limit?: number },
|
|
424
|
+
opts?: { templateIds?: string[]; limit?: number; includeCreatedEventBlob?: boolean },
|
|
425
425
|
): Promise<JsActiveContract[]> {
|
|
426
426
|
return this.#client.queryActiveContracts(party, offset, opts);
|
|
427
427
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { buildChannelCredentials } from '../../../src/client/topology/utils';
|
|
4
|
+
|
|
5
|
+
describe('admin API channel credentials', () => {
|
|
6
|
+
it('encrypts a conventional admin port', () => {
|
|
7
|
+
expect(buildChannelCredentials('participant.example.com:5002')._isSecure()).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('encrypts the HTTPS port', () => {
|
|
11
|
+
expect(buildChannelCredentials('participant.example.com:443')._isSecure()).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('encrypts a loopback host by default', () => {
|
|
15
|
+
expect(buildChannelCredentials('localhost:2902')._isSecure()).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('drops encryption for a loopback name', () => {
|
|
19
|
+
expect(buildChannelCredentials('localhost:2902', true)._isSecure()).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('drops encryption for a loopback address', () => {
|
|
23
|
+
expect(buildChannelCredentials('127.0.0.1:2902', true)._isSecure()).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('drops encryption for a bracketed IPv6 loopback address', () => {
|
|
27
|
+
expect(buildChannelCredentials('[::1]:2902', true)._isSecure()).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('rejects an unencrypted channel to a remote host', () => {
|
|
31
|
+
expect(() => buildChannelCredentials('participant.example.com:5002', true)).toThrow(
|
|
32
|
+
/requires an encrypted channel/,
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('rejects an unencrypted channel to a host merely named after loopback', () => {
|
|
37
|
+
expect(() => buildChannelCredentials('localhost.example.com:5002', true)).toThrow(
|
|
38
|
+
/requires an encrypted channel/,
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('rejects an unencrypted channel to a public address in the loopback range shape', () => {
|
|
43
|
+
expect(() => buildChannelCredentials('128.0.0.1:2902', true)).toThrow(
|
|
44
|
+
/requires an encrypted channel/,
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
});
|
package/test/provider.test.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import type { CantonGrpcClientOptions } from '../src/client/topology/types';
|
|
4
|
+
|
|
5
|
+
const { grpcClientOptions } = vi.hoisted(() => ({
|
|
6
|
+
grpcClientOptions: [] as CantonGrpcClientOptions[],
|
|
7
|
+
}));
|
|
2
8
|
|
|
3
9
|
vi.mock('../src/auth/client-credentials-token-provider', () => ({
|
|
4
10
|
ClientCredentialsTokenProvider: class {},
|
|
@@ -10,7 +16,11 @@ vi.mock('../src/client/canton-client', () => ({
|
|
|
10
16
|
CantonClient: class {},
|
|
11
17
|
}));
|
|
12
18
|
vi.mock('../src/client/grpc', () => ({
|
|
13
|
-
CantonGrpcClient: class {
|
|
19
|
+
CantonGrpcClient: class {
|
|
20
|
+
constructor(options: CantonGrpcClientOptions) {
|
|
21
|
+
grpcClientOptions.push(options);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
14
24
|
}));
|
|
15
25
|
vi.mock('../src/open-api/runtime', () => ({ Configuration: class {} }));
|
|
16
26
|
|
|
@@ -98,3 +108,28 @@ describe('parseCantonChainUri', () => {
|
|
|
98
108
|
}
|
|
99
109
|
});
|
|
100
110
|
});
|
|
111
|
+
|
|
112
|
+
describe('createCantonChainProvider', () => {
|
|
113
|
+
beforeEach(() => {
|
|
114
|
+
grpcClientOptions.length = 0;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('leaves the admin channel encrypted for a non-local deployment', async () => {
|
|
118
|
+
const { createCantonChainProvider } = await loadProvider();
|
|
119
|
+
|
|
120
|
+
createCantonChainProvider({
|
|
121
|
+
uri: `${BASE}&token-url=http://token&client-id=cid&client-secret=secret`,
|
|
122
|
+
isLocal: false,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(grpcClientOptions[0]?.insecureTransport).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('drops admin channel encryption for a local deployment', async () => {
|
|
129
|
+
const { createCantonChainProvider } = await loadProvider();
|
|
130
|
+
|
|
131
|
+
createCantonChainProvider({ uri: BASE, isLocal: true });
|
|
132
|
+
|
|
133
|
+
expect(grpcClientOptions[0]?.insecureTransport).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
});
|
package/dist/AH32N3GF.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.ts"],"names":["parseCantonChainUri","uri","url","URL","adminApiHost","searchParams","get","Error","userId","actAsParam","actAs","split","map","party","trim","filter","length","walletUrl","tokenUrl","undefined","clientId","clientSecret","process","env","CANTON_CLIENT_SECRET","scope","audience","key","delete","jsonApiUrl","toString","replace","oauth2","createCantonChainProvider","isLocal","params","tokenProvider","createTokenProvider","configuration","Configuration","basePath","accessToken","getToken","client","CantonClient","grpcClient","CantonGrpcClient","host","LocalTokenProvider","admin","ClientCredentialsTokenProvider"],"mappings":"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","file":"AH32N3GF.js","sourcesContent":["import {\n ClientCredentialsTokenProvider,\n type ClientCredentialsTokenProviderConfig,\n} from './auth/client-credentials-token-provider';\nimport { LocalTokenProvider } from './auth/local-token-provider';\nimport type { TokenProvider } from './auth/token-provider';\nimport { CantonClient } from './client/canton-client';\nimport { CantonGrpcClient } from './client/grpc';\nimport type { ICantonClient } from './client/interface';\nimport { Configuration } from './open-api/runtime';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Provider Type\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * - {@link client} — JSON Ledger API (commands, queries, updates)\n * - {@link grpcClient} — gRPC Admin API (topology transactions, namespace queries)\n * - {@link tokenProvider} — Shared Bearer-token source used by both transports\n * - {@link walletUrl} — Canton Network validator wallet (scan-proxy CIP-56 endpoints)\n */\nexport type CantonChainProvider = {\n client: ICantonClient;\n grpcClient: CantonGrpcClient;\n tokenProvider: TokenProvider;\n /** Validator wallet URL for scan-proxy CIP-56 endpoints. Required. */\n walletUrl: string;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// URI Parsing\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CantonChainUriParams = {\n /** Base URL of the JSON Ledger API (e.g. \"http://localhost:5975\") */\n jsonApiUrl: string;\n /** Host:port of the gRPC Admin API (e.g. \"localhost:5076\") */\n adminApiHost: string;\n /** Ledger API user ID (default: \"participant_admin\") */\n userId: string;\n /** Parties granted `actAs` on localnet tokens (comma-separated in the URI). */\n actAs: string[];\n /** Validator wallet URL for scan-proxy CIP-56 endpoints (e.g. \"http://localhost:7201\"). Required. */\n walletUrl: string;\n /** OAuth2 client credentials config — present only for non-local environments */\n oauth2?: ClientCredentialsTokenProviderConfig;\n};\n\n/**\n * Parse a Canton chain provider URI into its constituent parts.\n *\n * URI format:\n * `<json-api-base>?admin-api=<host:port>&user-id=<id>&wallet-url=<url>[&token-url=...&client-id=...&client-secret=...&scope=...&audience=...]`\n *\n * The base URL (everything before the query string) is the JSON Ledger API endpoint.\n * Canton-specific params are extracted and removed; any remaining query params are\n * preserved on the JSON API URL.\n *\n * When `client-secret` is omitted from the URI, `CANTON_CLIENT_SECRET` is read from the\n * environment.\n */\nexport function parseCantonChainUri(uri: string): CantonChainUriParams {\n const url = new URL(uri);\n\n const adminApiHost = url.searchParams.get('admin-api');\n if (!adminApiHost) {\n throw new Error('Canton provider URI missing required \"admin-api\" query parameter');\n }\n\n const userId = url.searchParams.get('user-id') ?? 'participant_admin';\n const actAsParam = url.searchParams.get('act-as');\n const actAs =\n actAsParam\n ?.split(',')\n .map((party) => party.trim())\n .filter((party) => party.length > 0) ?? [];\n const walletUrl = url.searchParams.get('wallet-url');\n if (!walletUrl) {\n throw new Error('Canton provider URI missing required \"wallet-url\" query parameter');\n }\n const tokenUrl = url.searchParams.get('token-url') ?? undefined;\n const clientId = url.searchParams.get('client-id') ?? undefined;\n // Prefer URI param; fall back to env so secrets are not committed in provider configs.\n const clientSecret =\n url.searchParams.get('client-secret') ??\n // eslint-disable-next-line turbo/no-undeclared-env-vars -- runtime OAuth secret, not a turbo task input\n process.env.CANTON_CLIENT_SECRET ??\n undefined;\n const scope = url.searchParams.get('scope') ?? undefined;\n const audience = url.searchParams.get('audience') ?? undefined;\n\n for (const key of [\n 'admin-api',\n 'user-id',\n 'act-as',\n 'wallet-url',\n 'sequencer-url',\n 'sequencer-validators',\n 'sequencer-quorum',\n 'token-url',\n 'client-id',\n 'client-secret',\n 'scope',\n 'audience',\n ]) {\n url.searchParams.delete(key);\n }\n\n const jsonApiUrl = url.toString().replace(/\\/$/, '');\n\n const oauth2 =\n tokenUrl && clientId && clientSecret\n ? { tokenUrl, clientId, clientSecret, scope, audience }\n : undefined;\n\n return {\n jsonApiUrl,\n adminApiHost,\n userId,\n actAs,\n walletUrl,\n oauth2,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Provider Factory\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type CreateCantonChainProviderOptions = {\n /** Raw provider URI (from provider config) */\n uri: string;\n /** When true, uses LocalTokenProvider (self-signed JWTs) instead of OAuth2 */\n isLocal: boolean;\n};\n\n/**\n * Create a {@link CantonChainProvider} from a provider URI.\n *\n * - **isLocal=true**: Uses {@link LocalTokenProvider} with admin-level access (self-signed JWTs).\n * - **isLocal=false**: Uses {@link ClientCredentialsTokenProvider} with OAuth2 client\n * credentials extracted from the URI query parameters.\n */\nexport function createCantonChainProvider({\n uri,\n isLocal,\n}: CreateCantonChainProviderOptions): CantonChainProvider {\n const params = parseCantonChainUri(uri);\n\n const tokenProvider = createTokenProvider(params, isLocal);\n\n // ── JSON Ledger API Client ──────────────────────────────────────────\n const configuration = new Configuration({\n basePath: params.jsonApiUrl,\n accessToken: () => tokenProvider.getToken(),\n });\n const client = new CantonClient(configuration, params.userId, {\n walletUrl: params.walletUrl,\n tokenProvider,\n });\n\n // ── gRPC Admin API Client ───────────────────────────────────────────\n const grpcClient = new CantonGrpcClient({\n host: params.adminApiHost,\n tokenProvider,\n });\n\n return {\n client,\n grpcClient,\n tokenProvider,\n walletUrl: params.walletUrl,\n };\n}\n\nfunction createTokenProvider(params: CantonChainUriParams, isLocal: boolean): TokenProvider {\n if (isLocal) {\n return new LocalTokenProvider({\n userId: params.userId,\n actAs: params.actAs,\n admin: true,\n });\n }\n\n // TODO(canton): add other prod auth methods (direct JWT passthrough, etc.).\n if (!params.oauth2) {\n throw new Error(\n 'Canton provider requires OAuth2 credentials (token-url, client-id, client-secret in URI or CANTON_CLIENT_SECRET)',\n );\n }\n\n return new ClientCredentialsTokenProvider(params.oauth2);\n}\n"]}
|
package/dist/IA2UQ4WQ.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/grpc.ts"],"names":["DEFAULT_GRPC_CLIENT_OPTIONS","CantonGrpcClient","opts","tokenProvider","synchronizerId","GrpcTransport","host","channelCredentials","buildChannelCredentials","tls","clientOptions","grpcClientOptions","TopologyManagerReadServiceClient","TopologyManagerWriteServiceClient","SynchronizerConnectivityServiceClient","token","getToken","Authorization","response","listConnectedSynchronizers","meta","synchronizer","connectedSynchronizers","CantonProtocolError","mapping","serial","generateTransactions","GenerateTransactionsRequest","create","proposals","GenerateTransactionsRequest_Proposal","operation","Enums_TopologyChangeOp","ADD_REPLACE","store","synchronizerStore","generated","generatedTransactions","getNamespaceDelegation","namespaceFingerprint","listNamespaceDelegation","ListNamespaceDelegationRequest","baseQuery","headStateBaseQuery","filterNamespace","filterTargetKeyFingerprint","results","flatMap","result","item","publicKey","targetKey","namespace","targetKeyFingerprint","computePublicKeyFingerprint","isRootDelegation","context","getDecentralizedNamespaceDefinition","listDecentralizedNamespaceDefinition","ListDecentralizedNamespaceDefinitionRequest","decentralizedNamespace","threshold","owners","getPartyToKeyMapping","partyId","listPartyToKeyMapping","ListPartyToKeyMappingRequest","filterParty","party","signingKeyFingerprints","signingKeys","map","key","getPartyToParticipantMapping","listPartyToParticipant","ListPartyToParticipantRequest","filterParticipant","participants","participant","participantUid","permission","createNamespaceDelegationTx","params","buildNamespaceDelegationMapping","publicKeyDer","createDecentralizedNamespaceDefinitionTx","computeDecentralizedNamespace","buildDecentralizedNamespaceDefinitionMapping","updateDecentralizedNamespaceDefinitionTx","createPartyToKeyTx","buildPartyToKeyMapping","signingPublicKeyDers","createPartyToParticipantTx","buildPartyToParticipantMapping","participantIds","submitTopologyTransactions","transactions","length","CantonError","addTransactions","AddTransactionsRequest","close"],"mappings":"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","file":"IA2UQ4WQ.js","sourcesContent":["import {\n AddTransactionsRequest,\n Enums_TopologyChangeOp,\n GenerateTransactionsRequest,\n GenerateTransactionsRequest_Proposal,\n ListDecentralizedNamespaceDefinitionRequest,\n ListNamespaceDelegationRequest,\n ListPartyToKeyMappingRequest,\n ListPartyToParticipantRequest,\n type SignedTopologyTransaction,\n TopologyManagerReadServiceClient,\n TopologyManagerWriteServiceClient,\n type TopologyMapping,\n} from '@canton-network/core-ledger-proto';\nimport { GrpcTransport } from '@protobuf-ts/grpc-transport';\n\nimport type { TokenProvider } from '../auth/token-provider';\nimport { CantonError, CantonProtocolError } from '../errors';\nimport {\n buildDecentralizedNamespaceDefinitionMapping,\n buildNamespaceDelegationMapping,\n buildPartyToKeyMapping,\n buildPartyToParticipantMapping,\n} from './topology/mappings';\nimport { SynchronizerConnectivityServiceClient } from './topology/synchronizer-connectivity';\nimport type {\n CantonGrpcClientOptions,\n CreateDecentralizedNamespaceDefinitionTxParams,\n CreateNamespaceDelegationTxParams,\n CreatePartyToKeyMappingTxParams,\n CreatePartyToParticipantMappingTxParams,\n DecentralizedNamespaceDefinitionState,\n GeneratedTopologyTransaction,\n NamespaceDelegationState,\n PartyToKeyMappingState,\n PartyToParticipantMappingState,\n UpdateDecentralizedNamespaceDefinitionTxParams,\n} from './topology/types';\nimport {\n buildChannelCredentials,\n computeDecentralizedNamespace,\n headStateBaseQuery,\n synchronizerStore,\n} from './topology/utils';\nimport { computePublicKeyFingerprint } from './utils';\n\n/** Default gRPC client options: 128 MiB message-size limits for large admin responses. */\nconst DEFAULT_GRPC_CLIENT_OPTIONS = {\n 'grpc.max_receive_message_length': 128 * 1024 * 1024,\n 'grpc.max_send_message_length': 128 * 1024 * 1024,\n} as const;\n\n/**\n * gRPC client for the Canton participant admin Topology Manager API.\n *\n * Exposes read queries for topology mappings and write helpers that call\n * `GenerateTransactions` to produce unsigned topology transactions and\n * `AddTransactions` to submit signed ones.\n *\n * A fresh Bearer token is attached to each RPC via {@link TokenProvider}.\n */\nexport class CantonGrpcClient {\n readonly #transport: GrpcTransport;\n readonly #topologyRead: TopologyManagerReadServiceClient;\n readonly #topologyWrite: TopologyManagerWriteServiceClient;\n readonly #connectivity: SynchronizerConnectivityServiceClient;\n readonly #tokenProvider: TokenProvider;\n #synchronizerId?: string;\n\n /**\n * @param opts - Admin API host, auth, optional synchronizer id, and optional TLS.\n */\n constructor(opts: CantonGrpcClientOptions) {\n this.#tokenProvider = opts.tokenProvider;\n this.#synchronizerId = opts.synchronizerId;\n this.#transport = new GrpcTransport({\n host: opts.host,\n channelCredentials: buildChannelCredentials(opts.host, opts.tls),\n clientOptions: opts.grpcClientOptions ?? DEFAULT_GRPC_CLIENT_OPTIONS,\n });\n this.#topologyRead = new TopologyManagerReadServiceClient(this.#transport);\n this.#topologyWrite = new TopologyManagerWriteServiceClient(this.#transport);\n this.#connectivity = new SynchronizerConnectivityServiceClient(this.#transport);\n }\n\n /** Returns per-RPC gRPC metadata with a fresh Bearer token. */\n async #getMeta(): Promise<Record<string, string>> {\n const token = await this.#tokenProvider.getToken();\n return { Authorization: `Bearer ${token}` };\n }\n\n /**\n * Returns the client synchronizer id, discovering it on first use when omitted at construction.\n *\n * @throws {CantonProtocolError} If the participant exposes no synchronizer store.\n */\n async #getSynchronizerId(): Promise<string> {\n if (this.#synchronizerId) {\n return this.#synchronizerId;\n }\n this.#synchronizerId = await this.#discoverSynchronizerId();\n return this.#synchronizerId;\n }\n\n /**\n * Resolves the logical id of the first synchronizer the participant is connected to.\n *\n * @throws {CantonProtocolError} If the participant is not connected to any synchronizer.\n */\n async #discoverSynchronizerId(): Promise<string> {\n const { response } = await this.#connectivity.listConnectedSynchronizers(\n {},\n { meta: await this.#getMeta() },\n );\n for (const synchronizer of response.connectedSynchronizers) {\n if (synchronizer.synchronizerId) {\n return synchronizer.synchronizerId;\n }\n }\n throw new CantonProtocolError('Participant is not connected to any synchronizer');\n }\n\n /**\n * Calls `GenerateTransactions` for a single ADD_REPLACE mapping.\n *\n * @param synchronizerId - Synchronizer store to target.\n * @param mapping - Topology mapping to encode into the transaction.\n * @param serial - Topology serial (`0` lets Canton auto-determine).\n * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).\n * @throws {CantonProtocolError} If the RPC returns no generated transaction.\n */\n async #generateTopologyTransaction(\n synchronizerId: string,\n mapping: TopologyMapping,\n serial: number,\n ): Promise<GeneratedTopologyTransaction> {\n const { response } = await this.#topologyWrite.generateTransactions(\n GenerateTransactionsRequest.create({\n proposals: [\n GenerateTransactionsRequest_Proposal.create({\n operation: Enums_TopologyChangeOp.ADD_REPLACE,\n serial,\n mapping,\n store: synchronizerStore(synchronizerId),\n }),\n ],\n }),\n { meta: await this.#getMeta() },\n );\n\n const generated = response.generatedTransactions[0];\n if (!generated) {\n throw new CantonProtocolError('GenerateTransactions returned no topology transaction');\n }\n return generated;\n }\n\n /**\n * Lists Namespace Delegation (NSD) mappings for a namespace.\n *\n * Queries topology head state on the synchronizer. Returns every result from\n * the list RPC.\n *\n * @param namespaceFingerprint - Namespace to filter on (for root NSD, the owner key fingerprint).\n * @returns All matching NSD mappings, or an empty array if none exist.\n */\n async getNamespaceDelegation(\n namespaceFingerprint: string,\n ): Promise<NamespaceDelegationState[]> {\n const synchronizerId = await this.#getSynchronizerId();\n const { response } = await this.#topologyRead.listNamespaceDelegation(\n ListNamespaceDelegationRequest.create({\n baseQuery: headStateBaseQuery(synchronizerId),\n filterNamespace: namespaceFingerprint,\n // Empty string = no target-key filter; return all delegations for this namespace.\n filterTargetKeyFingerprint: '',\n }),\n { meta: await this.#getMeta() },\n );\n\n return response.results.flatMap((result) => {\n const item = result.item;\n const publicKey = item?.targetKey?.publicKey;\n if (!item || !publicKey) {\n return [];\n }\n return [\n {\n namespace: item.namespace,\n targetKeyFingerprint: computePublicKeyFingerprint(publicKey),\n isRootDelegation: item.isRootDelegation,\n serial: result.context?.serial ?? 0,\n },\n ];\n });\n }\n\n /**\n * Lists Decentralized Namespace Definition (DND) mappings for a namespace.\n *\n * Queries topology head state on the synchronizer. For a party id `hint::1220…`,\n * pass the `1220…` suffix as `namespaceFingerprint`.\n *\n * @param namespaceFingerprint - Decentralized namespace fingerprint to filter on.\n * @returns All matching DND mappings, or an empty array if none exist.\n */\n async getDecentralizedNamespaceDefinition(\n namespaceFingerprint: string,\n ): Promise<DecentralizedNamespaceDefinitionState[]> {\n const synchronizerId = await this.#getSynchronizerId();\n const { response } = await this.#topologyRead.listDecentralizedNamespaceDefinition(\n ListDecentralizedNamespaceDefinitionRequest.create({\n baseQuery: headStateBaseQuery(synchronizerId),\n filterNamespace: namespaceFingerprint,\n }),\n { meta: await this.#getMeta() },\n );\n\n return response.results.flatMap((result) => {\n const item = result.item;\n if (!item) {\n return [];\n }\n return [\n {\n namespace: item.decentralizedNamespace,\n threshold: item.threshold,\n owners: [...item.owners],\n serial: result.context?.serial ?? 0,\n },\n ];\n });\n }\n\n /**\n * Lists Party-to-Key (PTK) mappings for a party.\n *\n * Queries topology head state on the synchronizer.\n *\n * @param partyId - Full party identifier (e.g. `hint::1220…`).\n * @returns All matching PTK mappings, or an empty array if none exist.\n */\n async getPartyToKeyMapping(partyId: string): Promise<PartyToKeyMappingState[]> {\n const synchronizerId = await this.#getSynchronizerId();\n const { response } = await this.#topologyRead.listPartyToKeyMapping(\n ListPartyToKeyMappingRequest.create({\n baseQuery: headStateBaseQuery(synchronizerId),\n filterParty: partyId,\n }),\n { meta: await this.#getMeta() },\n );\n\n return response.results.flatMap((result) => {\n const item = result.item;\n if (!item) {\n return [];\n }\n return [\n {\n party: item.party,\n threshold: item.threshold,\n signingKeyFingerprints: item.signingKeys.map((key) =>\n computePublicKeyFingerprint(key.publicKey),\n ),\n serial: result.context?.serial ?? 0,\n },\n ];\n });\n }\n\n /**\n * Lists Party-to-Participant (PTP) mappings for a party.\n *\n * Queries topology head state on the synchronizer.\n *\n * @param partyId - Full party identifier (e.g. `hint::1220…`).\n * @param proposals - If `true`, query pending proposals instead of authorized mappings.\n * @returns All matching PTP mappings, or an empty array if none exist.\n */\n async getPartyToParticipantMapping(\n partyId: string,\n proposals = false,\n ): Promise<PartyToParticipantMappingState[]> {\n const synchronizerId = await this.#getSynchronizerId();\n const { response } = await this.#topologyRead.listPartyToParticipant(\n ListPartyToParticipantRequest.create({\n baseQuery: headStateBaseQuery(synchronizerId, proposals),\n filterParty: partyId,\n // Empty string = no participant filter; return all hosting mappings for this party.\n filterParticipant: '',\n }),\n { meta: await this.#getMeta() },\n );\n\n return response.results.flatMap((result) => {\n const item = result.item;\n if (!item) {\n return [];\n }\n return [\n {\n party: item.party,\n threshold: item.threshold,\n participants: item.participants.map((participant) => ({\n participantUid: participant.participantUid,\n permission: participant.permission,\n })),\n serial: result.context?.serial ?? 0,\n },\n ];\n });\n }\n\n /**\n * Builds an unsigned Namespace Delegation (NSD) topology transaction.\n *\n * Calls `GenerateTransactions` with an ADD_REPLACE mapping. The returned\n * `transactionHash` must be signed by the namespace key.\n *\n * @param params - Owner public key and optional serial.\n * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).\n */\n async createNamespaceDelegationTx(\n params: CreateNamespaceDelegationTxParams,\n ): Promise<GeneratedTopologyTransaction> {\n const synchronizerId = await this.#getSynchronizerId();\n const mapping = buildNamespaceDelegationMapping(params.publicKeyDer);\n return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);\n }\n\n /**\n * Builds an unsigned Decentralized Namespace Definition (DND) topology transaction.\n *\n * The decentralized namespace id is derived from `params.owners`. All owners\n * must sign the transaction hash.\n *\n * @param params - Owner fingerprints, threshold, and optional serial.\n * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).\n */\n async createDecentralizedNamespaceDefinitionTx(\n params: CreateDecentralizedNamespaceDefinitionTxParams,\n ): Promise<GeneratedTopologyTransaction> {\n const synchronizerId = await this.#getSynchronizerId();\n const decentralizedNamespace = computeDecentralizedNamespace(params.owners);\n const mapping = buildDecentralizedNamespaceDefinitionMapping(\n decentralizedNamespace,\n params.threshold,\n params.owners,\n );\n return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);\n }\n\n async updateDecentralizedNamespaceDefinitionTx(\n params: UpdateDecentralizedNamespaceDefinitionTxParams,\n ): Promise<GeneratedTopologyTransaction> {\n const synchronizerId = await this.#getSynchronizerId();\n const mapping = buildDecentralizedNamespaceDefinitionMapping(\n params.namespace,\n params.threshold,\n params.owners,\n );\n return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);\n }\n\n /**\n * Builds an unsigned Party-to-Key (PTK) topology transaction.\n *\n * Decentralized namespace owners must sign the transaction hash.\n *\n * @param params - Party id, signing keys, threshold, and optional serial.\n * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).\n */\n async createPartyToKeyTx(\n params: CreatePartyToKeyMappingTxParams,\n ): Promise<GeneratedTopologyTransaction> {\n const synchronizerId = await this.#getSynchronizerId();\n const mapping = buildPartyToKeyMapping(\n params.partyId,\n params.signingPublicKeyDers,\n params.threshold,\n );\n return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);\n }\n\n /**\n * Builds an unsigned Party-to-Participant (PTP) topology transaction.\n *\n * Party owners sign the transaction hash. On submit, set `proposal: true` on the\n * signed transaction so the hosting participant can authorize via `Authorize`.\n *\n * @param params - Party id, participant ids, threshold, and optional serial.\n * @returns Unsigned topology transaction (`serializedTransaction`, `transactionHash`).\n */\n async createPartyToParticipantTx(\n params: CreatePartyToParticipantMappingTxParams,\n ): Promise<GeneratedTopologyTransaction> {\n const synchronizerId = await this.#getSynchronizerId();\n const mapping = buildPartyToParticipantMapping(\n params.partyId,\n params.participantIds,\n params.threshold,\n );\n return this.#generateTopologyTransaction(synchronizerId, mapping, params.serial ?? 0);\n }\n\n /**\n * Submits signed topology transactions to the synchronizer store.\n *\n * Multiple transactions are submitted atomically in one `AddTransactions` call.\n * When batching, sign `computeMultiTransactionHash` over all transaction hashes\n * and attach the same `MultiTransactionSignatures` to each entry.\n *\n * Set `proposal: true` on a transaction when the hosting participant must\n * authorize that mapping afterward.\n *\n * @param transactions - One or more signed topology transactions.\n * @throws {CantonError} If `transactions` is empty.\n */\n async submitTopologyTransactions(\n transactions: readonly SignedTopologyTransaction[],\n ): Promise<void> {\n if (transactions.length === 0) {\n throw new CantonError('AddTransactions requires at least one transaction');\n }\n const synchronizerId = await this.#getSynchronizerId();\n await this.#topologyWrite.addTransactions(\n AddTransactionsRequest.create({\n transactions: [...transactions],\n store: synchronizerStore(synchronizerId),\n }),\n { meta: await this.#getMeta() },\n );\n }\n\n /** Closes the underlying gRPC transport. */\n close(): void {\n this.#transport.close();\n }\n}\n"]}
|
package/dist/QAKOQQ7E.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/topology/utils.ts"],"names":["HASH_PURPOSE_DECENTRALIZED_NAMESPACE","HASH_PURPOSE_MULTI_TRANSACTION","computeDecentralizedNamespace","owners","sorted","sort","parts","owner","ownerBytes","Buffer","from","lengthPrefix","alloc","writeUInt32BE","length","push","bytesToHex","cantonMultihash","concat","computeMultiTransactionHash","hashes","left","right","compare","countBuffer","hash","lengthBuffer","synchronizerStore","synchronizerId","StoreId","create","store","oneofKind","synchronizer","id","headStateBaseQuery","proposals","BaseQuery","timeQuery","headState","Empty","buildChannelCredentials","host","tls","ChannelCredentials","createSsl","rootCert","clientKey","clientCert","endsWith","createInsecure"],"mappings":";;;;;;AASA,IAAMA,oCAAAA,GAAuC,EAAA;AAG7C,IAAMC,8BAAAA,GAAiC,EAAA;AAQhC,SAASC,8BAA8BC,MAAAA,EAAgB;AAC1D,EAAA,MAAMC,MAAAA,GAAS;AAAID,IAAAA,GAAAA;IAAQE,IAAAA,EAAI;AAC/B,EAAA,MAAMC,QAAkB,EAAA;AACxB,EAAA,KAAA,MAAWC,SAASH,MAAAA,EAAQ;AACxB,IAAA,MAAMI,UAAAA,GAAaC,MAAAA,CAAOC,IAAAA,CAAKH,KAAAA,EAAO,OAAA,CAAA;AACtC,IAAA,MAAMI,YAAAA,GAAeF,MAAAA,CAAOG,KAAAA,CAAM,CAAA,CAAA;AAClCD,IAAAA,YAAAA,CAAaE,aAAAA,CAAcL,WAAWM,MAAM,CAAA;AAC5CR,IAAAA,KAAAA,CAAMS,IAAAA,CAAKJ,cAAcH,UAAAA,CAAAA;AAC7B,EAAA;AACA,EAAA,OAAOQ,WAAWC,eAAAA,CAAgBjB,oCAAAA,EAAsCS,OAAOS,MAAAA,CAAOZ,KAAAA,CAAAA,CAAAA,CAAAA;AAC1F;AAVgBJ,MAAAA,CAAAA,6BAAAA,EAAAA,+BAAAA,CAAAA;AAmBT,SAASiB,4BAA4BC,MAAAA,EAAoB;AAC5D,EAAA,MAAMhB,MAAAA,GAAS;AAAIgB,IAAAA,GAAAA;AAAQf,GAAAA,CAAAA,IAAAA,CAAK,CAACgB,IAAAA,EAAMC,KAAAA,KACnCb,MAAAA,CAAOc,OAAAA,CAAQd,MAAAA,CAAOC,IAAAA,CAAKW,IAAAA,CAAAA,EAAOZ,MAAAA,CAAOC,IAAAA,CAAKY,KAAAA,CAAAA,CAAAA,CAAAA;AAElD,EAAA,MAAMhB,QAAkB,EAAA;AACxB,EAAA,MAAMkB,WAAAA,GAAcf,MAAAA,CAAOG,KAAAA,CAAM,CAAA,CAAA;AACjCY,EAAAA,WAAAA,CAAYX,aAAAA,CAAcT,OAAOU,MAAM,CAAA;AACvCR,EAAAA,KAAAA,CAAMS,KAAKS,WAAAA,CAAAA;AACX,EAAA,KAAA,MAAWC,QAAQrB,MAAAA,EAAQ;AACvB,IAAA,MAAMsB,YAAAA,GAAejB,MAAAA,CAAOG,KAAAA,CAAM,CAAA,CAAA;AAClCc,IAAAA,YAAAA,CAAab,aAAAA,CAAcY,KAAKX,MAAM,CAAA;AACtCR,IAAAA,KAAAA,CAAMS,IAAAA,CAAKW,YAAAA,EAAcjB,MAAAA,CAAOC,IAAAA,CAAKe,IAAAA,CAAAA,CAAAA;AACzC,EAAA;AACA,EAAA,OAAOR,eAAAA,CAAgBhB,8BAAAA,EAAgCQ,MAAAA,CAAOS,MAAAA,CAAOZ,KAAAA,CAAAA,CAAAA;AACzE;AAdgBa,MAAAA,CAAAA,2BAAAA,EAAAA,6BAAAA,CAAAA;AAqBT,SAASQ,kBAAkBC,cAAAA,EAAsB;AACpD,EAAA,OAAOC,QAAQC,MAAAA,CAAO;IAClBC,KAAAA,EAAO;MAAEC,SAAAA,EAAW,cAAA;MAAgBC,YAAAA,EAAc;QAAEC,EAAAA,EAAIN;AAAe;AAAE;GAC7E,CAAA;AACJ;AAJgBD,MAAAA,CAAAA,iBAAAA,EAAAA,mBAAAA,CAAAA;AAWT,SAASQ,kBAAAA,CAAmBP,cAAAA,EAAwBQ,SAAAA,GAAY,KAAA,EAAK;AACxE,EAAA,OAAOC,UAAUP,MAAAA,CAAO;AACpBC,IAAAA,KAAAA,EAAOJ,kBAAkBC,cAAAA,CAAAA;IACzBU,SAAAA,EAAW;MAAEN,SAAAA,EAAW,WAAA;MAAaO,SAAAA,EAAWC,KAAAA,CAAMV,MAAAA,CAAO,EAAC;AAAG,KAAA;AACjEM,IAAAA;GACJ,CAAA;AACJ;AANgBD,MAAAA,CAAAA,kBAAAA,EAAAA,oBAAAA,CAAAA;AAcT,SAASM,uBAAAA,CAAwBC,MAAcC,GAAAA,EAAgB;AAClE,EAAA,IAAIA,GAAAA,EAAK;AACL,IAAA,OAAOC,mBAAmBC,SAAAA,CAAUF,GAAAA,CAAIG,UAAUH,GAAAA,CAAII,SAAAA,EAAWJ,IAAIK,UAAU,CAAA;AACnF,EAAA;AACA,EAAA,OAAON,IAAAA,CAAKO,SAAS,MAAA,CAAA,GACfL,mBAAmBC,SAAAA,EAAS,GAC5BD,mBAAmBM,cAAAA,EAAc;AAC3C;AAPgBT,MAAAA,CAAAA,uBAAAA,EAAAA,yBAAAA,CAAAA","file":"QAKOQQ7E.js","sourcesContent":["import { BaseQuery, Empty, StoreId } from '@canton-network/core-ledger-proto';\nimport { ChannelCredentials } from '@grpc/grpc-js';\n\nimport { bytesToHex } from '@layerzerolabs/common-encoding-utils';\n\nimport { cantonMultihash } from '../utils';\nimport type { TlsOptions } from './types';\n\n/** Canton hash purpose for decentralized namespace derivation. */\nconst HASH_PURPOSE_DECENTRALIZED_NAMESPACE = 37;\n\n/** Canton hash purpose for multi-transaction topology signing. */\nconst HASH_PURPOSE_MULTI_TRANSACTION = 55;\n\n/**\n * Computes the decentralized namespace fingerprint from owner key fingerprints.\n *\n * Owners are sorted lexicographically, then hashed as\n * `1220` + SHA256(purpose=37 || for each owner: len(utf8) || utf8).\n */\nexport function computeDecentralizedNamespace(owners: string[]): string {\n const sorted = [...owners].sort();\n const parts: Buffer[] = [];\n for (const owner of sorted) {\n const ownerBytes = Buffer.from(owner, 'utf-8');\n const lengthPrefix = Buffer.alloc(4);\n lengthPrefix.writeUInt32BE(ownerBytes.length);\n parts.push(lengthPrefix, ownerBytes);\n }\n return bytesToHex(cantonMultihash(HASH_PURPOSE_DECENTRALIZED_NAMESPACE, Buffer.concat(parts)));\n}\n\n/**\n * Combines topology transaction hashes into the digest Canton expects signed.\n *\n * Hashes are sorted lexicographically, count-prefixed, each length-prefixed, then\n * hashed with purpose 55. Pass a single hash when signing one transaction —\n * Canton always uses this multi-transaction format for `AddTransactions`.\n */\nexport function computeMultiTransactionHash(hashes: Uint8Array[]): Uint8Array {\n const sorted = [...hashes].sort((left, right) =>\n Buffer.compare(Buffer.from(left), Buffer.from(right)),\n );\n const parts: Buffer[] = [];\n const countBuffer = Buffer.alloc(4);\n countBuffer.writeUInt32BE(sorted.length);\n parts.push(countBuffer);\n for (const hash of sorted) {\n const lengthBuffer = Buffer.alloc(4);\n lengthBuffer.writeUInt32BE(hash.length);\n parts.push(lengthBuffer, Buffer.from(hash));\n }\n return cantonMultihash(HASH_PURPOSE_MULTI_TRANSACTION, Buffer.concat(parts));\n}\n\n/**\n * Builds a topology `StoreId` scoped to a synchronizer.\n *\n * Used as the `store` field on topology read/write RPC requests.\n */\nexport function synchronizerStore(synchronizerId: string): StoreId {\n return StoreId.create({\n store: { oneofKind: 'synchronizer', synchronizer: { id: synchronizerId } },\n });\n}\n\n/**\n * Builds a topology `BaseQuery` at synchronizer head state.\n *\n * Used as the `baseQuery` field on topology list RPC requests.\n */\nexport function headStateBaseQuery(synchronizerId: string, proposals = false): BaseQuery {\n return BaseQuery.create({\n store: synchronizerStore(synchronizerId),\n timeQuery: { oneofKind: 'headState', headState: Empty.create({}) },\n proposals,\n });\n}\n\n/**\n * Builds gRPC channel credentials for the Canton admin API.\n *\n * Uses explicit TLS when `tls` is set, default SSL for hosts ending in `:443`,\n * and insecure credentials otherwise.\n */\nexport function buildChannelCredentials(host: string, tls?: TlsOptions): ChannelCredentials {\n if (tls) {\n return ChannelCredentials.createSsl(tls.rootCert, tls.clientKey, tls.clientCert);\n }\n return host.endsWith(':443')\n ? ChannelCredentials.createSsl()\n : ChannelCredentials.createInsecure();\n}\n"]}
|