@layerzerolabs/common-canton 0.2.114 → 0.2.116
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/.turbo/turbo-build.log +632 -631
- package/.turbo/turbo-test.log +51 -15
- package/LICENSE +23 -0
- package/dist/{CJ2WHLYC.js → EZIA6KIP.js} +3 -10
- package/dist/EZIA6KIP.js.map +1 -0
- package/dist/PQI7CWCR.js +19 -0
- package/dist/PQI7CWCR.js.map +1 -0
- package/dist/daml-serde.d.ts +1 -8
- package/dist/daml-serde.d.ts.map +1 -1
- package/dist/daml-serde.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +21 -15
- package/src/daml-serde.ts +1 -12
- package/src/index.ts +2 -0
- package/src/types.ts +13 -0
- package/test/daml-serde.test.ts +1 -1
- package/dist/CJ2WHLYC.js.map +0 -1
- package/dist/EYZBXTU6.js +0 -13
- package/dist/EYZBXTU6.js.map +0 -1
- package/test/mocks/scripts/capture-disclosure.ts +0 -252
- package/test/mocks/scripts/capture-external-requests.ts +0 -184
- package/test/mocks/scripts/capture-internal-requests.ts +0 -122
- package/test/mocks/scripts/capture-unhappy-paths.ts +0 -263
- package/test/mocks/scripts/capture-utils.ts +0 -215
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/**
|
|
4
|
-
* Captures disclosure flow using SecretBox contract.
|
|
5
|
-
*
|
|
6
|
-
* Scenario:
|
|
7
|
-
* 1. Alice creates a SecretBox with Bob as the "opener"
|
|
8
|
-
* 2. Bob is NOT an observer - he can't see the contract normally
|
|
9
|
-
* 3. Alice creates disclosure and shares it with Bob
|
|
10
|
-
* 4. Bob uses disclosure to exercise OpenBox choice (flexible controller)
|
|
11
|
-
*
|
|
12
|
-
* Usage:
|
|
13
|
-
* tsx test/mocks/scripts/capture-disclosure.ts
|
|
14
|
-
*
|
|
15
|
-
* Output:
|
|
16
|
-
* test/mocks/captured-disclosure.json
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import type { ContractId } from '@daml/types';
|
|
20
|
-
import * as path from 'path';
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
MnemonicSignerAdapter,
|
|
24
|
-
SignatureFormat,
|
|
25
|
-
SignatureType,
|
|
26
|
-
} from '@layerzerolabs/ver-signer-adapter';
|
|
27
|
-
import { CantonClient } from '../../../src/client/index.js';
|
|
28
|
-
// Import test contracts
|
|
29
|
-
import { packageId as testPackageId } from '../../../src/daml/sdk-test-0.0.1/lib/index.js';
|
|
30
|
-
import { SecretBox } from '../../../src/daml/sdk-test-0.0.1/lib/SdkTest/module.js';
|
|
31
|
-
import { Configuration } from '../../../src/open-api/runtime.js';
|
|
32
|
-
import { CantonSdk } from '../../../src/sdk/index.js';
|
|
33
|
-
import type { ExternalSignature } from '../../../src/types.js';
|
|
34
|
-
import {
|
|
35
|
-
CANTON_URL,
|
|
36
|
-
type CapturedInteraction,
|
|
37
|
-
createCapturingFetch,
|
|
38
|
-
createOperationContext,
|
|
39
|
-
EXTERNAL_PARTY_DERIVATION_PATH,
|
|
40
|
-
EXTERNAL_PARTY_ID,
|
|
41
|
-
EXTERNAL_PARTY_JWT_TOKEN,
|
|
42
|
-
EXTERNAL_PARTY_KEY_FINGERPRINT,
|
|
43
|
-
EXTERNAL_PARTY_MNEMONIC,
|
|
44
|
-
EXTERNAL_PARTY_USER_ID,
|
|
45
|
-
INTERNAL_PARTY_ID,
|
|
46
|
-
INTERNAL_PARTY_JWT_TOKEN,
|
|
47
|
-
INTERNAL_PARTY_USER_ID,
|
|
48
|
-
printEndpointSummary,
|
|
49
|
-
saveInteractions,
|
|
50
|
-
} from './capture-utils.js';
|
|
51
|
-
|
|
52
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
53
|
-
// Signing Helper (for Bob - external party)
|
|
54
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
55
|
-
|
|
56
|
-
async function signTransaction(hash: string, party: string): Promise<ExternalSignature> {
|
|
57
|
-
const signer = new MnemonicSignerAdapter({
|
|
58
|
-
mnemonicConfig: {
|
|
59
|
-
getMnemonic: async () => ({
|
|
60
|
-
mnemonic: EXTERNAL_PARTY_MNEMONIC,
|
|
61
|
-
path: EXTERNAL_PARTY_DERIVATION_PATH,
|
|
62
|
-
}),
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
const hashBytes = Uint8Array.from(Buffer.from(hash, 'base64'));
|
|
66
|
-
const { createHash } = await import('crypto');
|
|
67
|
-
const messageHash = createHash('sha256').update(hashBytes).digest();
|
|
68
|
-
|
|
69
|
-
const derSignature = await signer.sign({
|
|
70
|
-
data: messageHash,
|
|
71
|
-
signatureType: SignatureType.ECDSA,
|
|
72
|
-
format: SignatureFormat.DER,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
party,
|
|
77
|
-
signature: Buffer.from(derSignature).toString('base64'),
|
|
78
|
-
signedBy: EXTERNAL_PARTY_KEY_FINGERPRINT,
|
|
79
|
-
format: 'SIGNATURE_FORMAT_DER',
|
|
80
|
-
signingAlgorithmSpec: 'SIGNING_ALGORITHM_SPEC_EC_DSA_SHA_256',
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
85
|
-
// Disclosure Flow
|
|
86
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
87
|
-
|
|
88
|
-
async function captureDisclosureFlow(
|
|
89
|
-
aliceSdk: CantonSdk,
|
|
90
|
-
bobSdk: CantonSdk,
|
|
91
|
-
setOperation: (name: string) => void,
|
|
92
|
-
): Promise<void> {
|
|
93
|
-
// 1. Alice creates a SecretBox with Bob as opener
|
|
94
|
-
// Bob is NOT an observer - he can't see this contract!
|
|
95
|
-
setOperation('alice_create_secret_box');
|
|
96
|
-
console.log('1. Alice creates SecretBox with Bob as opener...');
|
|
97
|
-
|
|
98
|
-
const createCmd = aliceSdk.buildCreate(
|
|
99
|
-
SecretBox as any,
|
|
100
|
-
{
|
|
101
|
-
owner: INTERNAL_PARTY_ID,
|
|
102
|
-
opener: EXTERNAL_PARTY_ID, // Bob can open it...
|
|
103
|
-
secret: 'test-secret-not-a-real-secret-just-testing',
|
|
104
|
-
isOpen: false,
|
|
105
|
-
},
|
|
106
|
-
testPackageId,
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
const createResult = await aliceSdk.submit({ actAs: [INTERNAL_PARTY_ID] }, [createCmd]);
|
|
110
|
-
const createWait = await aliceSdk.waitForCommand(createResult.commandId, {
|
|
111
|
-
parties: [INTERNAL_PARTY_ID],
|
|
112
|
-
beginExclusive: createResult.completionOffset,
|
|
113
|
-
timeoutMs: 60_000,
|
|
114
|
-
});
|
|
115
|
-
if (createWait.status !== 'accepted') throw new Error(`Create failed: ${createWait.status}`);
|
|
116
|
-
|
|
117
|
-
const createUpdate = await aliceSdk.fetchTransaction(createWait.updateId, [INTERNAL_PARTY_ID]);
|
|
118
|
-
const createdEventWrapper = (createUpdate.events ?? []).find((e) => 'CreatedEvent' in e);
|
|
119
|
-
if (!createdEventWrapper || !('CreatedEvent' in createdEventWrapper))
|
|
120
|
-
throw new Error('No contract created');
|
|
121
|
-
|
|
122
|
-
const secretBoxId = createdEventWrapper.CreatedEvent.contractId;
|
|
123
|
-
console.log(` Created: ${secretBoxId.slice(0, 20)}...`);
|
|
124
|
-
console.log(` Bob is opener but NOT observer - he needs disclosure!`);
|
|
125
|
-
|
|
126
|
-
// 2. Alice creates disclosure of the SecretBox for Bob
|
|
127
|
-
setOperation('alice_create_disclosure');
|
|
128
|
-
console.log('2. Alice creates disclosure...');
|
|
129
|
-
|
|
130
|
-
const disclosure = await aliceSdk.createDisclosure(
|
|
131
|
-
secretBoxId as ContractId<typeof SecretBox>,
|
|
132
|
-
[INTERNAL_PARTY_ID],
|
|
133
|
-
);
|
|
134
|
-
if (!disclosure) throw new Error('Failed to create disclosure');
|
|
135
|
-
|
|
136
|
-
console.log(` Disclosure created`);
|
|
137
|
-
console.log(` Template: ${disclosure.templateId}`);
|
|
138
|
-
console.log(` Blob: ${disclosure.createdEventBlob.slice(0, 40)}...`);
|
|
139
|
-
|
|
140
|
-
// 3. Bob exercises OpenBox WITH disclosure
|
|
141
|
-
// Without disclosure, Bob can't see the contract and would get an error
|
|
142
|
-
setOperation('bob_prepare_open_box');
|
|
143
|
-
console.log('3. Bob exercises OpenBox with disclosure (signed)...');
|
|
144
|
-
|
|
145
|
-
const exerciseCmd = bobSdk.buildExercise(
|
|
146
|
-
SecretBox.OpenBox,
|
|
147
|
-
secretBoxId as ContractId<typeof SecretBox>,
|
|
148
|
-
{},
|
|
149
|
-
testPackageId,
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
// Prepare with disclosure - Bob can now see Alice's SecretBox
|
|
153
|
-
const prepared = await bobSdk.prepareForSigning(
|
|
154
|
-
{ actAs: [EXTERNAL_PARTY_ID] },
|
|
155
|
-
[exerciseCmd],
|
|
156
|
-
{ disclosedContracts: [disclosure] }, // <-- Disclosure required!
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
setOperation('bob_submit_open_box');
|
|
160
|
-
const signature = await signTransaction(prepared.preparedTransactionHash, EXTERNAL_PARTY_ID);
|
|
161
|
-
const exerciseResult = await bobSdk.submitSigned(prepared, [signature]);
|
|
162
|
-
|
|
163
|
-
setOperation('bob_wait_open_box');
|
|
164
|
-
const exerciseWait = await bobSdk.waitForCommand(exerciseResult.commandId, {
|
|
165
|
-
parties: [EXTERNAL_PARTY_ID],
|
|
166
|
-
beginExclusive: exerciseResult.completionOffset,
|
|
167
|
-
timeoutMs: 60_000,
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
if (exerciseWait.status !== 'accepted') {
|
|
171
|
-
throw new Error(`OpenBox failed: ${JSON.stringify(exerciseWait)}`);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
setOperation('bob_fetch_result');
|
|
175
|
-
const exerciseUpdate = await bobSdk.fetchTransaction(exerciseWait.updateId, [
|
|
176
|
-
EXTERNAL_PARTY_ID,
|
|
177
|
-
]);
|
|
178
|
-
const openedBoxWrapper = (exerciseUpdate.events ?? []).find((e) => 'CreatedEvent' in e);
|
|
179
|
-
const openedBox =
|
|
180
|
-
openedBoxWrapper && 'CreatedEvent' in openedBoxWrapper
|
|
181
|
-
? openedBoxWrapper.CreatedEvent
|
|
182
|
-
: null;
|
|
183
|
-
console.log(` Box opened! New contract: ${openedBox?.contractId?.slice(0, 20)}...`);
|
|
184
|
-
|
|
185
|
-
// 4. Verify the box is now open
|
|
186
|
-
setOperation('alice_verify_opened');
|
|
187
|
-
console.log('4. Alice verifies the box is open...');
|
|
188
|
-
|
|
189
|
-
const verifyContract = await aliceSdk.get(
|
|
190
|
-
openedBox!.contractId as ContractId<typeof SecretBox>,
|
|
191
|
-
[INTERNAL_PARTY_ID],
|
|
192
|
-
);
|
|
193
|
-
const isOpen = (verifyContract?.payload as any)?.isOpen;
|
|
194
|
-
console.log(` isOpen: ${isOpen}`);
|
|
195
|
-
|
|
196
|
-
if (isOpen) {
|
|
197
|
-
console.log(" ✓ Disclosure flow complete! Bob opened Alice's box.");
|
|
198
|
-
} else {
|
|
199
|
-
throw new Error('Box should be open!');
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
204
|
-
// Main
|
|
205
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
206
|
-
|
|
207
|
-
async function main() {
|
|
208
|
-
console.log('Capturing disclosure flow: SecretBox\n');
|
|
209
|
-
console.log('Scenario: Alice creates box, Bob is opener but NOT observer.');
|
|
210
|
-
console.log('Bob needs disclosure to see and exercise the contract.\n');
|
|
211
|
-
|
|
212
|
-
const captured: CapturedInteraction[] = [];
|
|
213
|
-
const { setOperation, getOperation } = createOperationContext();
|
|
214
|
-
|
|
215
|
-
// Alice (internal party) - owner of the SecretBox
|
|
216
|
-
const aliceConfig = new Configuration({
|
|
217
|
-
basePath: CANTON_URL,
|
|
218
|
-
fetchApi: createCapturingFetch({ captured, getOperation }),
|
|
219
|
-
headers: { Authorization: `Bearer ${INTERNAL_PARTY_JWT_TOKEN}` },
|
|
220
|
-
});
|
|
221
|
-
const aliceClient = new CantonClient(aliceConfig, INTERNAL_PARTY_USER_ID);
|
|
222
|
-
const aliceSdk = new CantonSdk(aliceClient);
|
|
223
|
-
|
|
224
|
-
// Bob (external party) - opener, needs disclosure
|
|
225
|
-
const bobConfig = new Configuration({
|
|
226
|
-
basePath: CANTON_URL,
|
|
227
|
-
fetchApi: createCapturingFetch({ captured, getOperation }),
|
|
228
|
-
headers: { Authorization: `Bearer ${EXTERNAL_PARTY_JWT_TOKEN}` },
|
|
229
|
-
});
|
|
230
|
-
const bobClient = new CantonClient(bobConfig, EXTERNAL_PARTY_USER_ID);
|
|
231
|
-
const bobSdk = new CantonSdk(bobClient);
|
|
232
|
-
|
|
233
|
-
await captureDisclosureFlow(aliceSdk, bobSdk, setOperation);
|
|
234
|
-
|
|
235
|
-
const outputFile = path.join(import.meta.dirname, '..', 'captured-disclosure.json');
|
|
236
|
-
saveInteractions(outputFile, captured);
|
|
237
|
-
printEndpointSummary(captured);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
main().catch(async (err) => {
|
|
241
|
-
console.error('Error:', err.message);
|
|
242
|
-
if (err.response && typeof err.response.text === 'function') {
|
|
243
|
-
try {
|
|
244
|
-
const body = await err.response.text();
|
|
245
|
-
console.error('Response body:', body);
|
|
246
|
-
} catch {
|
|
247
|
-
/* ignore */
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
console.error(err.stack);
|
|
251
|
-
process.exit(1);
|
|
252
|
-
});
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/**
|
|
4
|
-
* Captures real Canton API interactions for external party (signed submission) flow.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* tsx test/mocks/scripts/capture-external-requests.ts
|
|
8
|
-
*
|
|
9
|
-
* Output:
|
|
10
|
-
* test/mocks/captured-external-requests.json
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { ContractId } from '@daml/types';
|
|
14
|
-
import * as path from 'path';
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
MnemonicSignerAdapter,
|
|
18
|
-
SignatureFormat,
|
|
19
|
-
SignatureType,
|
|
20
|
-
} from '@layerzerolabs/ver-signer-adapter';
|
|
21
|
-
import { CantonClient } from '../../../src/client/index.js';
|
|
22
|
-
// Import SDK test contracts
|
|
23
|
-
import { packageId } from '../../../src/daml/sdk-test-0.0.1/lib/index.js';
|
|
24
|
-
import { SimpleAsset } from '../../../src/daml/sdk-test-0.0.1/lib/SdkTest/module.js';
|
|
25
|
-
import { Configuration } from '../../../src/open-api/runtime.js';
|
|
26
|
-
import { CantonSdk } from '../../../src/sdk/index.js';
|
|
27
|
-
import type { ExternalSignature } from '../../../src/types.js';
|
|
28
|
-
import {
|
|
29
|
-
CANTON_URL,
|
|
30
|
-
type CapturedInteraction,
|
|
31
|
-
createCapturingFetch,
|
|
32
|
-
createOperationContext,
|
|
33
|
-
EXTERNAL_PARTY_DERIVATION_PATH,
|
|
34
|
-
EXTERNAL_PARTY_ID,
|
|
35
|
-
EXTERNAL_PARTY_JWT_TOKEN,
|
|
36
|
-
EXTERNAL_PARTY_KEY_FINGERPRINT,
|
|
37
|
-
EXTERNAL_PARTY_MNEMONIC,
|
|
38
|
-
EXTERNAL_PARTY_USER_ID,
|
|
39
|
-
printEndpointSummary,
|
|
40
|
-
saveInteractions,
|
|
41
|
-
} from './capture-utils.js';
|
|
42
|
-
|
|
43
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
44
|
-
// Signing Helper
|
|
45
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
46
|
-
|
|
47
|
-
async function signTransaction(hash: string, party: string): Promise<ExternalSignature> {
|
|
48
|
-
const signer = new MnemonicSignerAdapter({
|
|
49
|
-
mnemonicConfig: {
|
|
50
|
-
getMnemonic: async () => ({
|
|
51
|
-
mnemonic: EXTERNAL_PARTY_MNEMONIC,
|
|
52
|
-
path: EXTERNAL_PARTY_DERIVATION_PATH,
|
|
53
|
-
}),
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
const hashBytes = Uint8Array.from(Buffer.from(hash, 'base64'));
|
|
57
|
-
const { createHash } = await import('crypto');
|
|
58
|
-
const messageHash = createHash('sha256').update(hashBytes).digest();
|
|
59
|
-
|
|
60
|
-
const derSignature = await signer.sign({
|
|
61
|
-
data: messageHash,
|
|
62
|
-
signatureType: SignatureType.ECDSA,
|
|
63
|
-
format: SignatureFormat.DER,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
party,
|
|
68
|
-
signature: Buffer.from(derSignature).toString('base64'),
|
|
69
|
-
signedBy: EXTERNAL_PARTY_KEY_FINGERPRINT,
|
|
70
|
-
format: 'SIGNATURE_FORMAT_DER',
|
|
71
|
-
signingAlgorithmSpec: 'SIGNING_ALGORITHM_SPEC_EC_DSA_SHA_256',
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
76
|
-
// Capture Flow
|
|
77
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
78
|
-
|
|
79
|
-
async function captureExternalSigningFlow(
|
|
80
|
-
sdk: CantonSdk,
|
|
81
|
-
setOperation: (name: string) => void,
|
|
82
|
-
): Promise<void> {
|
|
83
|
-
// 1. Prepare Create
|
|
84
|
-
setOperation('external_prepare_create');
|
|
85
|
-
const payload = {
|
|
86
|
-
owner: EXTERNAL_PARTY_ID,
|
|
87
|
-
value: '200',
|
|
88
|
-
description: 'Test asset for external party flow',
|
|
89
|
-
};
|
|
90
|
-
const createCmd = sdk.buildCreate(SimpleAsset as any, payload, packageId);
|
|
91
|
-
const preparedCreate = await sdk.prepareForSigning({ actAs: [EXTERNAL_PARTY_ID] }, [createCmd]);
|
|
92
|
-
|
|
93
|
-
// 2. Submit Signed Create
|
|
94
|
-
setOperation('external_submit_create');
|
|
95
|
-
const createSignature = await signTransaction(
|
|
96
|
-
preparedCreate.preparedTransactionHash,
|
|
97
|
-
EXTERNAL_PARTY_ID,
|
|
98
|
-
);
|
|
99
|
-
const createResult = await sdk.submitSigned(preparedCreate, [createSignature]);
|
|
100
|
-
|
|
101
|
-
// 3. Wait for Create
|
|
102
|
-
setOperation('external_wait_create');
|
|
103
|
-
const createCompletion = await sdk.waitForCommand(createResult.commandId, {
|
|
104
|
-
parties: [EXTERNAL_PARTY_ID],
|
|
105
|
-
beginExclusive: createResult.completionOffset,
|
|
106
|
-
timeoutMs: 60_000,
|
|
107
|
-
});
|
|
108
|
-
if (createCompletion.status !== 'accepted') throw new Error('Create rejected');
|
|
109
|
-
|
|
110
|
-
// 4. Fetch Contract ID
|
|
111
|
-
setOperation('external_fetch_created_contract_id');
|
|
112
|
-
const update = await sdk.fetchTransaction(createCompletion.updateId, [EXTERNAL_PARTY_ID]);
|
|
113
|
-
const createdWrapper = (update.events ?? []).find((e) => 'CreatedEvent' in e);
|
|
114
|
-
const contractId =
|
|
115
|
-
createdWrapper && 'CreatedEvent' in createdWrapper
|
|
116
|
-
? createdWrapper.CreatedEvent.contractId
|
|
117
|
-
: undefined;
|
|
118
|
-
if (!contractId) throw new Error('No contract created');
|
|
119
|
-
|
|
120
|
-
// 5. Query Contract
|
|
121
|
-
setOperation('external_query_contract');
|
|
122
|
-
await sdk.get(contractId as ContractId<typeof SimpleAsset>, [EXTERNAL_PARTY_ID]);
|
|
123
|
-
|
|
124
|
-
// 6. Prepare Archive
|
|
125
|
-
setOperation('external_prepare_archive');
|
|
126
|
-
const archiveCmd = sdk.buildExercise(
|
|
127
|
-
SimpleAsset.Archive,
|
|
128
|
-
contractId as ContractId<typeof SimpleAsset>,
|
|
129
|
-
{},
|
|
130
|
-
packageId,
|
|
131
|
-
);
|
|
132
|
-
const preparedArchive = await sdk.prepareForSigning({ actAs: [EXTERNAL_PARTY_ID] }, [
|
|
133
|
-
archiveCmd,
|
|
134
|
-
]);
|
|
135
|
-
|
|
136
|
-
// 7. Submit Signed Archive
|
|
137
|
-
setOperation('external_submit_archive');
|
|
138
|
-
const archiveSignature = await signTransaction(
|
|
139
|
-
preparedArchive.preparedTransactionHash,
|
|
140
|
-
EXTERNAL_PARTY_ID,
|
|
141
|
-
);
|
|
142
|
-
const archiveResult = await sdk.submitSigned(preparedArchive, [archiveSignature]);
|
|
143
|
-
|
|
144
|
-
// 8. Wait for Archive
|
|
145
|
-
setOperation('external_wait_archive');
|
|
146
|
-
await sdk.waitForCommand(archiveResult.commandId, {
|
|
147
|
-
parties: [EXTERNAL_PARTY_ID],
|
|
148
|
-
beginExclusive: archiveResult.completionOffset,
|
|
149
|
-
timeoutMs: 60_000,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// 9. Verify Archived
|
|
153
|
-
setOperation('external_verify_archived');
|
|
154
|
-
await sdk.get(contractId as ContractId<typeof SimpleAsset>, [EXTERNAL_PARTY_ID]);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
158
|
-
// Main
|
|
159
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
160
|
-
|
|
161
|
-
async function main() {
|
|
162
|
-
console.log('Capturing external party requests...');
|
|
163
|
-
|
|
164
|
-
const captured: CapturedInteraction[] = [];
|
|
165
|
-
const { setOperation, getOperation } = createOperationContext();
|
|
166
|
-
|
|
167
|
-
const config = new Configuration({
|
|
168
|
-
basePath: CANTON_URL,
|
|
169
|
-
fetchApi: createCapturingFetch({ captured, getOperation }),
|
|
170
|
-
headers: { Authorization: `Bearer ${EXTERNAL_PARTY_JWT_TOKEN}` },
|
|
171
|
-
});
|
|
172
|
-
const sdk = new CantonSdk(new CantonClient(config, EXTERNAL_PARTY_USER_ID));
|
|
173
|
-
|
|
174
|
-
await captureExternalSigningFlow(sdk, setOperation);
|
|
175
|
-
|
|
176
|
-
const outputFile = path.join(import.meta.dirname, '..', 'captured-external-requests.json');
|
|
177
|
-
saveInteractions(outputFile, captured);
|
|
178
|
-
printEndpointSummary(captured);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
main().catch((err) => {
|
|
182
|
-
console.error('Error:', err.message);
|
|
183
|
-
process.exit(1);
|
|
184
|
-
});
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/**
|
|
4
|
-
* Captures real Canton API interactions for internal party (normal submission) flow.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* tsx test/mocks/scripts/capture-internal-requests.ts
|
|
8
|
-
*
|
|
9
|
-
* Output:
|
|
10
|
-
* test/mocks/captured-internal-requests.json
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { ContractId } from '@daml/types';
|
|
14
|
-
import * as path from 'path';
|
|
15
|
-
|
|
16
|
-
import { CantonClient } from '../../../src/client/index.js';
|
|
17
|
-
// Import SDK test contracts
|
|
18
|
-
import { packageId } from '../../../src/daml/sdk-test-0.0.1/lib/index.js';
|
|
19
|
-
import { SimpleAsset } from '../../../src/daml/sdk-test-0.0.1/lib/SdkTest/module.js';
|
|
20
|
-
import { Configuration } from '../../../src/open-api/runtime.js';
|
|
21
|
-
import { CantonSdk } from '../../../src/sdk/index.js';
|
|
22
|
-
import {
|
|
23
|
-
CANTON_URL,
|
|
24
|
-
type CapturedInteraction,
|
|
25
|
-
createCapturingFetch,
|
|
26
|
-
createOperationContext,
|
|
27
|
-
INTERNAL_PARTY_ID,
|
|
28
|
-
INTERNAL_PARTY_JWT_TOKEN,
|
|
29
|
-
INTERNAL_PARTY_USER_ID,
|
|
30
|
-
printEndpointSummary,
|
|
31
|
-
saveInteractions,
|
|
32
|
-
} from './capture-utils.js';
|
|
33
|
-
|
|
34
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
-
// Capture Flow
|
|
36
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
37
|
-
|
|
38
|
-
async function captureInternalPartyFlow(sdk: CantonSdk, setOperation: (name: string) => void) {
|
|
39
|
-
// 1. Connected Synchronizers
|
|
40
|
-
setOperation('list_synchronizers');
|
|
41
|
-
await sdk.connectedSynchronizers();
|
|
42
|
-
|
|
43
|
-
// 2. Create Contract
|
|
44
|
-
setOperation('create_contract');
|
|
45
|
-
const payload = {
|
|
46
|
-
owner: INTERNAL_PARTY_ID,
|
|
47
|
-
value: '100',
|
|
48
|
-
description: 'Test asset for internal party flow',
|
|
49
|
-
};
|
|
50
|
-
const createCmd = sdk.buildCreate(SimpleAsset as any, payload, packageId);
|
|
51
|
-
const submitResult = await sdk.submit({ actAs: [INTERNAL_PARTY_ID] }, [createCmd]);
|
|
52
|
-
|
|
53
|
-
// 3. Wait for Create
|
|
54
|
-
setOperation('wait_create');
|
|
55
|
-
const waitResult = await sdk.waitForCommand(submitResult.commandId, {
|
|
56
|
-
parties: [INTERNAL_PARTY_ID],
|
|
57
|
-
beginExclusive: submitResult.completionOffset,
|
|
58
|
-
timeoutMs: 60_000,
|
|
59
|
-
});
|
|
60
|
-
if (waitResult.status !== 'accepted') throw new Error('Create rejected');
|
|
61
|
-
|
|
62
|
-
// 4. Fetch Contract ID
|
|
63
|
-
setOperation('fetch_created_contract_id');
|
|
64
|
-
const update = await sdk.fetchTransaction(waitResult.updateId, [INTERNAL_PARTY_ID]);
|
|
65
|
-
const createdWrapper = (update.events ?? []).find((e) => 'CreatedEvent' in e);
|
|
66
|
-
const contractId = (
|
|
67
|
-
createdWrapper && 'CreatedEvent' in createdWrapper
|
|
68
|
-
? createdWrapper.CreatedEvent.contractId
|
|
69
|
-
: undefined
|
|
70
|
-
) as ContractId<typeof SimpleAsset>;
|
|
71
|
-
if (!contractId) throw new Error('No contract created');
|
|
72
|
-
|
|
73
|
-
// 5. Query Contract
|
|
74
|
-
setOperation('query_contract');
|
|
75
|
-
await sdk.get(contractId, [INTERNAL_PARTY_ID]);
|
|
76
|
-
|
|
77
|
-
// 6. Archive Contract
|
|
78
|
-
setOperation('archive_contract');
|
|
79
|
-
const archiveCmd = sdk.buildExercise(SimpleAsset.Archive, contractId, {}, packageId);
|
|
80
|
-
const archiveResult = await sdk.submit({ actAs: [INTERNAL_PARTY_ID] }, [archiveCmd]);
|
|
81
|
-
|
|
82
|
-
// 7. Wait for Archive
|
|
83
|
-
setOperation('wait_archive');
|
|
84
|
-
await sdk.waitForCommand(archiveResult.commandId, {
|
|
85
|
-
parties: [INTERNAL_PARTY_ID],
|
|
86
|
-
beginExclusive: archiveResult.completionOffset,
|
|
87
|
-
timeoutMs: 60_000,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// 8. Verify Archived
|
|
91
|
-
setOperation('verify_archived');
|
|
92
|
-
await sdk.get(contractId, [INTERNAL_PARTY_ID]);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
96
|
-
// Main
|
|
97
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
98
|
-
|
|
99
|
-
async function main() {
|
|
100
|
-
console.log('Capturing internal party requests...');
|
|
101
|
-
|
|
102
|
-
const captured: CapturedInteraction[] = [];
|
|
103
|
-
const { setOperation, getOperation } = createOperationContext();
|
|
104
|
-
|
|
105
|
-
const config = new Configuration({
|
|
106
|
-
basePath: CANTON_URL,
|
|
107
|
-
fetchApi: createCapturingFetch({ captured, getOperation }),
|
|
108
|
-
headers: { Authorization: `Bearer ${INTERNAL_PARTY_JWT_TOKEN}` },
|
|
109
|
-
});
|
|
110
|
-
const sdk = new CantonSdk(new CantonClient(config, INTERNAL_PARTY_USER_ID));
|
|
111
|
-
|
|
112
|
-
await captureInternalPartyFlow(sdk, setOperation);
|
|
113
|
-
|
|
114
|
-
const outputFile = path.join(import.meta.dirname, '..', 'captured-internal-requests.json');
|
|
115
|
-
saveInteractions(outputFile, captured);
|
|
116
|
-
printEndpointSummary(captured);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
main().catch((err) => {
|
|
120
|
-
console.error('Error:', err.message);
|
|
121
|
-
process.exit(1);
|
|
122
|
-
});
|