@canton-network/core-tx-visualizer 0.4.0 → 0.6.0
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/Tx.test.js +7 -1
- package/dist/hashing_scheme_v2.d.ts +2 -0
- package/dist/hashing_scheme_v2.d.ts.map +1 -1
- package/dist/hashing_scheme_v2.js +37 -21
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +10 -0
- package/package.json +2 -2
package/dist/Tx.test.js
CHANGED
|
@@ -4,7 +4,7 @@ import { expect, test } from '@jest/globals';
|
|
|
4
4
|
import { PreparedTransaction } from '@canton-network/core-ledger-proto';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
7
|
-
import { decodePreparedTransaction } from '.';
|
|
7
|
+
import { decodePreparedTransaction, hashPreparedTransaction } from '.';
|
|
8
8
|
import camelcaseKeys from 'camelcase-keys';
|
|
9
9
|
test('decode a base 64 encoded prepared tx', async () => {
|
|
10
10
|
const base64EncodedPreparedTx = 'Cp8GCgMyLjESATAa8AUKATDCPukFCuYFCgMyLjESQjAwNTUwODAyZGRiMTYzNzFmNWZjNmQzNjRlNmNkNGIzMjgzYTllYjVjMGNjYjEyMWFlMzY4Y2RlYmJhZDBmYmY1NhoOQWRtaW5Xb3JrZmxvd3MiXgpAMmEzOGI5NjNmNmFiZjQ1Yjc2YzcwMmY5NzAwYmZkOTA2MDU1NTg3MmFmOTE1ZWY3ZjhmNjg3OTVlMmM4MzFiZBIUQ2FudG9uLkludGVybmFsLlBpbmcaBFBpbmcqtgJyswIKXgpAMmEzOGI5NjNmNmFiZjQ1Yjc2YzcwMmY5NzAwYmZkOTA2MDU1NTg3MmFmOTE1ZWY3ZjhmNjg3OTVlMmM4MzFiZBIUQ2FudG9uLkludGVybmFsLlBpbmcaBFBpbmcSDwoCaWQSCUIHcGluZ19pZBJdCglpbml0aWF0b3ISUDpOb3BlcmF0b3I6OjEyMjBkNDRmYzFjM2JhMGI1YmRmN2I5NTZlZTcxYmM5NGViZTJkMjMyNThkYzI2OGZkZjA4MjRmYmFlZmYyYzYxNDI0EmEKCXJlc3BvbmRlchJUOlJwYXJ0aWNpcGFudDE6OjEyMjBkNDRmYzFjM2JhMGI1YmRmN2I5NTZlZTcxYmM5NGViZTJkMjMyNThkYzI2OGZkZjA4MjRmYmFlZmYyYzYxNDI0Mk5vcGVyYXRvcjo6MTIyMGQ0NGZjMWMzYmEwYjViZGY3Yjk1NmVlNzFiYzk0ZWJlMmQyMzI1OGRjMjY4ZmRmMDgyNGZiYWVmZjJjNjE0MjQ6Tm9wZXJhdG9yOjoxMjIwZDQ0ZmMxYzNiYTBiNWJkZjdiOTU2ZWU3MWJjOTRlYmUyZDIzMjU4ZGMyNjhmZGYwODI0ZmJhZWZmMmM2MTQyNDpScGFydGljaXBhbnQxOjoxMjIwZDQ0ZmMxYzNiYTBiNWJkZjdiOTU2ZWU3MWJjOTRlYmUyZDIzMjU4ZGMyNjhmZGYwODI0ZmJhZWZmMmM2MTQyNCIiEiBr2qJTURRRnXWp6y1EyXQiB69cfe50kJw0eYN1UF39nhL1ARJ2Ck5vcGVyYXRvcjo6MTIyMGQ0NGZjMWMzYmEwYjViZGY3Yjk1NmVlNzFiYzk0ZWJlMmQyMzI1OGRjMjY4ZmRmMDgyNGZiYWVmZjJjNjE0MjQSJGYyZWM0ZDhmLWNjYzEtNDAyYi1iMjc4LTc1NTZmZGQyYjQxMhpMd2FsbGV0OjoxMjIwZTdiMjNlYTUyZWI1YzY3MmZiMGIxY2RiYzkxNjkyMmZmZWQzZGQ3Njc2YzIyM2E2MDU2NjQzMTVlMmQ0M2VkZCokYTMyODE2MmUtNzI4ZS00ZTA1LWFjNzgtYjM0ZjA3MDk4M2JhMK7Y9/LU944D';
|
|
@@ -16,3 +16,9 @@ test('decode a base 64 encoded prepared tx', async () => {
|
|
|
16
16
|
const message = PreparedTransaction.fromJson(camelCasePreparedTx);
|
|
17
17
|
expect(message === preparedTx);
|
|
18
18
|
});
|
|
19
|
+
test('hash from preparedTx ledger api call should match calculated hash', async () => {
|
|
20
|
+
const preparedTxFromLedgerAPi = 'f97Cv1BO7QS7jmSY03p56JGsPf60Vx/ABXmRub7iiQI=';
|
|
21
|
+
const preparedTx2 = 'CsoHCgMyLjESATAamwcKATDCPpQHCpEHCgMyLjESQjAwMTY4Nzc3ODEwNzU3MmJlZWVjYzQzODk3MmQxODQ4M2VhZDI1MGQxZDUwYmI2MzU3ZjdmYjhmNjdkY2U3ZDYzNRoNc3BsaWNlLXdhbGxldCKCAQpAZWI2ZTAxZWZhY2MzMzk3ZTIzYzZiZThiOWJlN2RiNGJmMzc2NzIyMTE5NzRkNjllMjRiNDg5ODBlMmY5OGI3ZRIhU3BsaWNlLldhbGxldC5UcmFuc2ZlclByZWFwcHJvdmFsGhtUcmFuc2ZlclByZWFwcHJvdmFsUHJvcG9zYWwqtQNysgMKggEKQGViNmUwMWVmYWNjMzM5N2UyM2M2YmU4YjliZTdkYjRiZjM3NjcyMjExOTc0ZDY5ZTI0YjQ4OTgwZTJmOThiN2USIVNwbGljZS5XYWxsZXQuVHJhbnNmZXJQcmVhcHByb3ZhbBobVHJhbnNmZXJQcmVhcHByb3ZhbFByb3Bvc2FsElcKCHJlY2VpdmVyEks6SWJvYjo6MTIyMDViZTNiOWQxNzc1NzNmZmZiNjhlYjI0NTk4NmY4OGI5ZGY1OGQ0NGNlNTc1ODE5MDc4OTcwNTgwZDg3ZDFkYzAScgoIcHJvdmlkZXISZjpkYXBwX3VzZXJfbG9jYWxuZXQtbG9jYWxwYXJ0eS0xOjoxMjIwM2E1MmZlNWFmM2I4N2UwNjk2MTgyYWM2NjhhNmNiMzE1ZGFiNGJkYzMwZGE5ZTViNmRkYTllYjcyODc4NDIxNhJeCgtleHBlY3RlZERzbxJPUk0KSzpJRFNPOjoxMjIwYmJkMDAwYjY5ODc1NzNiOGMwOWY0NDRlNGRmNTUwOWFmODk5N2I4MzkxMDlkN2UyYzIxMmQ1NDdmMGFmMDk1MDJJYm9iOjoxMjIwNWJlM2I5ZDE3NzU3M2ZmZmI2OGViMjQ1OTg2Zjg4YjlkZjU4ZDQ0Y2U1NzU4MTkwNzg5NzA1ODBkODdkMWRjMDpkYXBwX3VzZXJfbG9jYWxuZXQtbG9jYWxwYXJ0eS0xOjoxMjIwM2E1MmZlNWFmM2I4N2UwNjk2MTgyYWM2NjhhNmNiMzE1ZGFiNGJkYzMwZGE5ZTViNmRkYTllYjcyODc4NDIxNjpJYm9iOjoxMjIwNWJlM2I5ZDE3NzU3M2ZmZmI2OGViMjQ1OTg2Zjg4YjlkZjU4ZDQ0Y2U1NzU4MTkwNzg5NzA1ODBkODdkMWRjMCIiEiDBzeNcgqLvsssBxhNx7wP9pK71TsAprgz+a8jag/Lb3RL3ARJxCklib2I6OjEyMjA1YmUzYjlkMTc3NTczZmZmYjY4ZWIyNDU5ODZmODhiOWRmNThkNDRjZTU3NTgxOTA3ODk3MDU4MGQ4N2QxZGMwEiQ5NzU4ZTQ2ZS05ZmJlLTRmOTQtOTczZC04NWQ5ZTBmMTMyNzUaU2dsb2JhbC1kb21haW46OjEyMjBiYmQwMDBiNjk4NzU3M2I4YzA5ZjQ0NGU0ZGY1NTA5YWY4OTk3YjgzOTEwOWQ3ZTJjMjEyZDU0N2YwYWYwOTUwKiQ5NGJkYmFmNS0wYjJjLTQwYmMtOTZjZC1jM2M5YTlkODQ3ZDIw+eaGkdz0jwM=';
|
|
22
|
+
const hashResult = await hashPreparedTransaction(preparedTx2, 'base64');
|
|
23
|
+
expect(hashResult === preparedTxFromLedgerAPi);
|
|
24
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { PreparedTransaction } from '@canton-network/core-ledger-proto';
|
|
2
2
|
export declare function encodeString(value?: string): Promise<Uint8Array>;
|
|
3
3
|
export declare function computePreparedTransaction(preparedTransaction: PreparedTransaction): Promise<Uint8Array>;
|
|
4
|
+
export declare function computeSha256CantonHash(purpose: number, bytes: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
5
|
+
export declare function computeMultiHashForTopology(hashes: Uint8Array[]): Promise<Uint8Array<ArrayBufferLike>>;
|
|
4
6
|
//# sourceMappingURL=hashing_scheme_v2.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashing_scheme_v2.d.ts","sourceRoot":"","sources":["../src/hashing_scheme_v2.ts"],"names":[],"mappings":"AAGA,OAAO,EAOH,mBAAmB,EACtB,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"hashing_scheme_v2.d.ts","sourceRoot":"","sources":["../src/hashing_scheme_v2.ts"],"names":[],"mappings":"AAGA,OAAO,EAOH,mBAAmB,EACtB,MAAM,mCAAmC,CAAA;AA8C1C,wBAAsB,YAAY,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAG1E;AA4cD,wBAAsB,0BAA0B,CAC5C,mBAAmB,EAAE,mBAAmB,GACzC,OAAO,CAAC,UAAU,CAAC,CAErB;AAED,wBAAsB,uBAAuB,CACzC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,wCAQpB;AAED,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,UAAU,EAAE,wCAerE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { HashingSchemeVersion, } from '@canton-network/core-ledger-proto';
|
|
4
|
-
import { mkByteArray, sha256 } from './utils.js';
|
|
4
|
+
import { mkByteArray, sha256, toHex } from './utils.js';
|
|
5
5
|
// Hash purpose reserved for prepared transaction
|
|
6
6
|
const PREPARED_TRANSACTION_HASH_PURPOSE = Uint8Array.from([
|
|
7
7
|
0x00, 0x00, 0x00, 0x30,
|
|
@@ -68,16 +68,13 @@ async function encodeRepeated(values = [], encodeFn) {
|
|
|
68
68
|
}
|
|
69
69
|
function findSeed(nodeId, nodeSeeds) {
|
|
70
70
|
const seed = nodeSeeds.find((seed) => seed.nodeId.toString() === nodeId)?.seed;
|
|
71
|
-
if (!seed) {
|
|
72
|
-
throw new Error(`Seed for node ID ${nodeId} not found`);
|
|
73
|
-
}
|
|
74
71
|
return seed;
|
|
75
72
|
}
|
|
76
73
|
async function encodeIdentifier(identifier) {
|
|
77
74
|
return mkByteArray(await encodeString(identifier.packageId), await encodeRepeated(identifier.moduleName.split('.'), encodeString), await encodeRepeated(identifier.entityName.split('.'), encodeString));
|
|
78
75
|
}
|
|
79
76
|
async function encodeMetadata(metadata) {
|
|
80
|
-
return mkByteArray(
|
|
77
|
+
return mkByteArray(Uint8Array.from([0x01]), await encodeRepeated(metadata.submitterInfo?.actAs, encodeString), await encodeString(metadata.submitterInfo?.commandId), await encodeString(metadata.transactionUuid), await encodeInt32(metadata.mediatorGroup), await encodeString(metadata.synchronizerId), await encodeProtoOptional(metadata, 'minLedgerEffectiveTime', metadata.minLedgerEffectiveTime, encodeInt64), await encodeProtoOptional(metadata, 'maxLedgerEffectiveTime', metadata.maxLedgerEffectiveTime, encodeInt64), await encodeInt64(metadata.preparationTime), await encodeRepeated(metadata.inputContracts, encodeInputContract));
|
|
81
78
|
}
|
|
82
79
|
async function encodeCreateNode(create, nodeId, nodeSeeds) {
|
|
83
80
|
return create
|
|
@@ -85,7 +82,7 @@ async function encodeCreateNode(create, nodeId, nodeSeeds) {
|
|
|
85
82
|
: mkByteArray();
|
|
86
83
|
}
|
|
87
84
|
async function encodeExerciseNode(exercise, nodeId, nodesDict, nodeSeeds) {
|
|
88
|
-
return mkByteArray(NODE_ENCODING_VERSION, await encodeString(exercise.lfVersion), 1 /** Exercise node tag */, await encodeHash(findSeed(nodeId, nodeSeeds)), await encodeHexString(exercise.contractId), await encodeString(exercise.packageName), await encodeIdentifier(exercise.templateId), await encodeRepeated(exercise.signatories, encodeString), await encodeRepeated(exercise.actingParties, encodeString), await encodeProtoOptional(exercise, 'interfaceId', exercise.interfaceId, encodeIdentifier), await encodeString(exercise.choiceId), await encodeValue(exercise.chosenValue), await encodeBool(exercise.consuming), await encodeProtoOptional(exercise, 'exerciseResult', exercise.exerciseResult, encodeValue), await encodeRepeated(exercise.choiceObservers, encodeString), await encodeRepeated(exercise.children, encodeNodeId(nodesDict, nodeSeeds)));
|
|
85
|
+
return mkByteArray(NODE_ENCODING_VERSION, await encodeString(exercise.lfVersion), 1 /** Exercise node tag */, await encodeHash(findSeed(nodeId, nodeSeeds)), await encodeHexString(exercise.contractId), await encodeString(exercise.packageName), await encodeIdentifier(exercise.templateId), await encodeRepeated(exercise.signatories, encodeString), await encodeRepeated(exercise.stakeholders, encodeString), await encodeRepeated(exercise.actingParties, encodeString), await encodeProtoOptional(exercise, 'interfaceId', exercise.interfaceId, encodeIdentifier), await encodeString(exercise.choiceId), await encodeValue(exercise.chosenValue), await encodeBool(exercise.consuming), await encodeProtoOptional(exercise, 'exerciseResult', exercise.exerciseResult, encodeValue), await encodeRepeated(exercise.choiceObservers, encodeString), await encodeRepeated(exercise.children, encodeNodeId(nodesDict, nodeSeeds)));
|
|
89
86
|
}
|
|
90
87
|
async function encodeFetchNode(fetch) {
|
|
91
88
|
return mkByteArray(NODE_ENCODING_VERSION, await encodeString(fetch.lfVersion), 2 /** Fetch node tag */, await encodeHexString(fetch.contractId), await encodeString(fetch.packageName), await encodeIdentifier(fetch.templateId), await encodeRepeated(fetch.signatories, encodeString), await encodeRepeated(fetch.stakeholders, encodeString), await encodeProtoOptional(fetch, 'interfaceId', fetch.interfaceId, encodeIdentifier), await encodeRepeated(fetch.actingParties, encodeString));
|
|
@@ -104,49 +101,49 @@ async function encodeValue(value) {
|
|
|
104
101
|
return Uint8Array.from([0]); // Unit value
|
|
105
102
|
}
|
|
106
103
|
else if (value.sum.oneofKind === 'bool') {
|
|
107
|
-
return mkByteArray(0x01, await encodeBool(value.sum.bool));
|
|
104
|
+
return mkByteArray(Uint8Array.from([0x01]), await encodeBool(value.sum.bool));
|
|
108
105
|
}
|
|
109
106
|
else if (value.sum.oneofKind === 'int64') {
|
|
110
|
-
return mkByteArray(0x02, await encodeInt64(parseInt(value.sum.int64)));
|
|
107
|
+
return mkByteArray(Uint8Array.from([0x02]), await encodeInt64(parseInt(value.sum.int64)));
|
|
111
108
|
}
|
|
112
109
|
else if (value.sum.oneofKind === 'numeric') {
|
|
113
|
-
return mkByteArray(0x03, await encodeString(value.sum.numeric));
|
|
110
|
+
return mkByteArray(Uint8Array.from([0x03]), await encodeString(value.sum.numeric));
|
|
114
111
|
}
|
|
115
112
|
else if (value.sum.oneofKind === 'timestamp') {
|
|
116
|
-
return mkByteArray(0x04, await
|
|
113
|
+
return mkByteArray(Uint8Array.from([0x04]), await encodeInt64(BigInt(value.sum.timestamp)));
|
|
117
114
|
}
|
|
118
115
|
else if (value.sum.oneofKind === 'date') {
|
|
119
|
-
return mkByteArray(0x05, await encodeInt32(value.sum.date));
|
|
116
|
+
return mkByteArray(Uint8Array.from([0x05]), await encodeInt32(value.sum.date));
|
|
120
117
|
}
|
|
121
118
|
else if (value.sum.oneofKind === 'party') {
|
|
122
|
-
return mkByteArray(0x06, await encodeString(value.sum.party));
|
|
119
|
+
return mkByteArray(Uint8Array.from([0x06]), await encodeString(value.sum.party));
|
|
123
120
|
}
|
|
124
121
|
else if (value.sum.oneofKind === 'text') {
|
|
125
|
-
return mkByteArray(0x07, await encodeString(value.sum.text));
|
|
122
|
+
return mkByteArray(Uint8Array.from([0x07]), await encodeString(value.sum.text));
|
|
126
123
|
}
|
|
127
124
|
else if (value.sum.oneofKind === 'contractId') {
|
|
128
|
-
return mkByteArray(0x08, await encodeHexString(value.sum.contractId));
|
|
125
|
+
return mkByteArray(Uint8Array.from([0x08]), await encodeHexString(value.sum.contractId));
|
|
129
126
|
}
|
|
130
127
|
else if (value.sum.oneofKind === 'optional') {
|
|
131
|
-
return mkByteArray(0x09, await encodeProtoOptional(value.sum.optional, 'value', value.sum.optional.value, encodeValue));
|
|
128
|
+
return mkByteArray(Uint8Array.from([0x09]), await encodeProtoOptional(value.sum.optional, 'value', value.sum.optional.value, encodeValue));
|
|
132
129
|
}
|
|
133
130
|
else if (value.sum.oneofKind === 'list') {
|
|
134
|
-
return mkByteArray(0x0a, await encodeRepeated(value.sum.list.elements, encodeValue));
|
|
131
|
+
return mkByteArray(Uint8Array.from([0x0a]), await encodeRepeated(value.sum.list.elements, encodeValue));
|
|
135
132
|
}
|
|
136
133
|
else if (value.sum.oneofKind === 'textMap') {
|
|
137
|
-
return mkByteArray(0x0b, await encodeRepeated(value.sum.textMap?.entries, encodeTextMapEntry));
|
|
134
|
+
return mkByteArray(Uint8Array.from([0x0b]), await encodeRepeated(value.sum.textMap?.entries, encodeTextMapEntry));
|
|
138
135
|
}
|
|
139
136
|
else if (value.sum.oneofKind === 'record') {
|
|
140
|
-
return mkByteArray(0x0c, await encodeProtoOptional(value.sum.record, 'recordId', value.sum.record.recordId, encodeIdentifier), await encodeRepeated(value.sum.record.fields, encodeRecordField));
|
|
137
|
+
return mkByteArray(Uint8Array.from([0x0c]), await encodeProtoOptional(value.sum.record, 'recordId', value.sum.record.recordId, encodeIdentifier), await encodeRepeated(value.sum.record.fields, encodeRecordField));
|
|
141
138
|
}
|
|
142
139
|
else if (value.sum.oneofKind === 'variant') {
|
|
143
|
-
return mkByteArray(0x0d, await encodeProtoOptional(value.sum.variant, 'variantId', value.sum.variant.variantId, encodeIdentifier), await encodeString(value.sum.variant.constructor), await encodeValue(value.sum.variant.value));
|
|
140
|
+
return mkByteArray(Uint8Array.from([0x0d]), await encodeProtoOptional(value.sum.variant, 'variantId', value.sum.variant.variantId, encodeIdentifier), await encodeString(value.sum.variant.constructor), await encodeValue(value.sum.variant.value));
|
|
144
141
|
}
|
|
145
142
|
else if (value.sum.oneofKind === 'enum') {
|
|
146
|
-
return mkByteArray(0x0e, await encodeProtoOptional(value.sum.enum, 'enumId', value.sum.enum.enumId, encodeIdentifier), await encodeString(value.sum.enum.constructor));
|
|
143
|
+
return mkByteArray(Uint8Array.from([0x0e]), await encodeProtoOptional(value.sum.enum, 'enumId', value.sum.enum.enumId, encodeIdentifier), await encodeString(value.sum.enum.constructor));
|
|
147
144
|
}
|
|
148
145
|
else if (value.sum.oneofKind === 'genMap') {
|
|
149
|
-
return mkByteArray(0x0f, await encodeRepeated(value.sum.genMap?.entries, encodeGenMapEntry));
|
|
146
|
+
return mkByteArray(Uint8Array.from([0x0f]), await encodeRepeated(value.sum.genMap?.entries, encodeGenMapEntry));
|
|
150
147
|
}
|
|
151
148
|
throw new Error('Unsupported value type: ' + JSON.stringify(value));
|
|
152
149
|
}
|
|
@@ -218,3 +215,22 @@ async function encodePreparedTransaction(preparedTransaction) {
|
|
|
218
215
|
export async function computePreparedTransaction(preparedTransaction) {
|
|
219
216
|
return sha256(await encodePreparedTransaction(preparedTransaction));
|
|
220
217
|
}
|
|
218
|
+
export async function computeSha256CantonHash(purpose, bytes) {
|
|
219
|
+
const encodedPurpose = await encodeInt32(purpose);
|
|
220
|
+
const hashInput = await mkByteArray(encodedPurpose, bytes);
|
|
221
|
+
const hashBytes = await sha256(hashInput);
|
|
222
|
+
const multiprefix = new Uint8Array([0x12, 0x20]);
|
|
223
|
+
return mkByteArray(multiprefix, hashBytes);
|
|
224
|
+
}
|
|
225
|
+
export async function computeMultiHashForTopology(hashes) {
|
|
226
|
+
const sortedHashes = hashes
|
|
227
|
+
.slice()
|
|
228
|
+
.sort((a, b) => toHex(a).localeCompare(toHex(b)));
|
|
229
|
+
const numHashesBytes = await encodeInt32(sortedHashes.length);
|
|
230
|
+
const concatenatedHashes = [numHashesBytes];
|
|
231
|
+
for (const h of sortedHashes) {
|
|
232
|
+
const lengthBytes = await encodeInt32(h.length);
|
|
233
|
+
concatenatedHashes.push(lengthBytes, h);
|
|
234
|
+
}
|
|
235
|
+
return mkByteArray(...concatenatedHashes);
|
|
236
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PreparedTransaction } from '@canton-network/core-ledger-proto';
|
|
2
|
+
export { computeSha256CantonHash, computeMultiHashForTopology, } from './hashing_scheme_v2.js';
|
|
2
3
|
/**
|
|
3
4
|
* Decodes a base64 encoded prepared transaction into a well-typed data model, generated directly from Protobuf definitions.
|
|
4
5
|
*
|
|
@@ -19,5 +20,4 @@ type ValidationResult = Record<string, {
|
|
|
19
20
|
locations: string[];
|
|
20
21
|
}>;
|
|
21
22
|
export declare const validateAuthorizedPartyIds: (preparedTransaction: string | PreparedTransaction, authorizedPartyIds: string[]) => ValidationResult;
|
|
22
|
-
export {};
|
|
23
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AAGvE,OAAO,EACH,uBAAuB,EACvB,2BAA2B,GAC9B,MAAM,wBAAwB,CAAA;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAClC,qBAAqB,MAAM,KAC5B,mBAGF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAChC,qBAAqB,MAAM,GAAG,mBAAmB,EACjD,SAAQ,QAAQ,GAAG,KAAgB,KACpC,OAAO,CAAC,MAAM,CAiBhB,CAAA;AAED,KAAK,gBAAgB,GAAG,MAAM,CAC1B,MAAM,EACN;IACI,YAAY,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,EAAE,CAAA;CACtB,CACJ,CAAA;AAED,eAAO,MAAM,0BAA0B,GACnC,qBAAqB,MAAM,GAAG,mBAAmB,EACjD,oBAAoB,MAAM,EAAE,KAC7B,gBAgEF,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { PreparedTransaction } from '@canton-network/core-ledger-proto';
|
|
4
4
|
import { computePreparedTransaction } from './hashing_scheme_v2.js';
|
|
5
5
|
import { fromBase64, toBase64, toHex } from './utils.js';
|
|
6
|
+
export { computeSha256CantonHash, computeMultiHashForTopology, } from './hashing_scheme_v2.js';
|
|
6
7
|
/**
|
|
7
8
|
* Decodes a base64 encoded prepared transaction into a well-typed data model, generated directly from Protobuf definitions.
|
|
8
9
|
*
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare function fromBase64(b64: string): Uint8Array;
|
|
|
4
4
|
export declare function toBase64(data: Uint8Array): string;
|
|
5
5
|
/** Take a byte buffer (Uint8Array) and encode it into a hex string */
|
|
6
6
|
export declare function toHex(bytes: Uint8Array): string;
|
|
7
|
+
export declare function fromHex(hex: string): Uint8Array;
|
|
7
8
|
export declare function sha256(message: string | Uint8Array): Promise<Uint8Array>;
|
|
8
9
|
/** Utility to concatenate byte arrays or single bytes */
|
|
9
10
|
export declare function mkByteArray(...args: (number | Uint8Array)[]): Promise<Uint8Array>;
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAQlD;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAOjD;AAED,sEAAsE;AACtE,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAI/C;AAED,wBAAsB,MAAM,CACxB,OAAO,EAAE,MAAM,GAAG,UAAU,GAC7B,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,yDAAyD;AACzD,wBAAsB,WAAW,CAC7B,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC,EAAE,GACjC,OAAO,CAAC,UAAU,CAAC,CAuBrB"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAQlD;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAOjD;AAED,sEAAsE;AACtE,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAI/C;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAU/C;AAED,wBAAsB,MAAM,CACxB,OAAO,EAAE,MAAM,GAAG,UAAU,GAC7B,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,yDAAyD;AACzD,wBAAsB,WAAW,CAC7B,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC,EAAE,GACjC,OAAO,CAAC,UAAU,CAAC,CAuBrB"}
|
package/dist/utils.js
CHANGED
|
@@ -25,6 +25,16 @@ export function toHex(bytes) {
|
|
|
25
25
|
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
26
26
|
.join('');
|
|
27
27
|
}
|
|
28
|
+
export function fromHex(hex) {
|
|
29
|
+
if (hex.length % 2 !== 0) {
|
|
30
|
+
throw new Error('Invalid hex string length');
|
|
31
|
+
}
|
|
32
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
33
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
34
|
+
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
35
|
+
}
|
|
36
|
+
return bytes;
|
|
37
|
+
}
|
|
28
38
|
export async function sha256(message) {
|
|
29
39
|
const msg = typeof message === 'string'
|
|
30
40
|
? new TextEncoder().encode(message)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canton-network/core-tx-visualizer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Decode and visualize prepared transactions from Canton",
|
|
6
6
|
"repository": "github:hyperledger-labs/splice-wallet-kernel",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"typescript": "^5.8.3"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@canton-network/core-ledger-proto": "^0.
|
|
28
|
+
"@canton-network/core-ledger-proto": "^0.7.0",
|
|
29
29
|
"@protobuf-ts/runtime": "^2.11.1",
|
|
30
30
|
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
|
31
31
|
"@swc/core": "^1.13.3",
|