diff --git a/core/test-token/.gitignore b/core/splice-codegen/.gitignore similarity index 100% rename from core/test-token/.gitignore rename to core/splice-codegen/.gitignore diff --git a/core/splice-codegen/README.md b/core/splice-codegen/README.md new file mode 100644 index 000000000..160d2dfa8 --- /dev/null +++ b/core/splice-codegen/README.md @@ -0,0 +1,166 @@ +# @canton-network/core-splice-codegen + +Typed wrappers around generated DAML JS packages used by Splice examples and SDK integrations. + +This package currently exposes two modules: + +- `TestToken` (from `@daml.js/test-token-v1`) +- `OTCTrade` (from `@daml.js/otc-trade`) + +## Installation + +```sh +yarn add @canton-network/core-splice-codegen +``` + +## Exports + +Top-level exports (from `src/index.ts`): + +- `TestToken` +- `OTCTrade` + +Each module has the same shape: + +- `DAR`: typed template references, package ID, and selected type exports +- `commands`: typed create/exercise command builders +- `utils`: helper utilities (currently `vetDar`) + +## Build + +From repository root: + +```sh +yarn workspace @canton-network/core-splice-codegen build +``` + +Build outputs: + +- ESM: `dist/index.js` +- CJS: `dist/index.cjs` +- Browser ESM: `dist/index.browser.js` +- Types: `dist/index.d.ts` + +## Quick Start + +```ts +import { TestToken, OTCTrade } from '@canton-network/core-splice-codegen' + +// Template references +console.log(TestToken.DAR.TestTokenV1.TokenRules.templateId) +console.log(OTCTrade.DAR.TradingApp.OTCTradeProposal.templateId) + +// Typed create command +const createRules = TestToken.commands.create.rules({ + admin: 'Alice::1220...', +}) + +// Typed exercise command +const settleTrade = OTCTrade.commands.exercise.otcTrade.settle({ + contractId: '00abc...', + choiceArgument: { + allocationsWithContext: {}, + }, +}) +``` + +## TestToken Module + +`TestToken.DAR` includes: + +- `packageId` +- `TestTokenV1` +- `TestTokenID` +- Types: `Token`, `TokenAllocation`, `TokenRules`, `TokenTransferOffer` + +`TestToken.commands.create`: + +- `transferOffer` +- `allocation` +- `rules` +- `token` + +`TestToken.commands.exercise.transferOffer`: + +- `accept` +- `reject` +- `withdraw` +- `update` + +`TestToken.commands.exercise.allocation`: + +- `executeTransfer` +- `cancel` +- `withdraw` + +`TestToken.commands.exercise.rules.transfer`: + +- `transfer` +- `publicFetch` + +`TestToken.commands.exercise.rules.allocation`: + +- `allocate` +- `publicFetch` + +`TestToken.utils`: + +- `vetDar(sdk, synchronizerId?)` + +## OTCTrade Module + +`OTCTrade.DAR` includes: + +- `packageId` +- `TradingApp` +- Types: `OTCTrade`, `OTCTradeProposal` + +`OTCTrade.commands.create`: + +- `otcTrade` +- `otcTradeProposal` + +`OTCTrade.commands.exercise.otcTrade`: + +- `settle` +- `cancel` + +`OTCTrade.commands.exercise.otcTradeProposal`: + +- `accept` +- `reject` +- `initiateSettlement` + +`OTCTrade.utils`: + +- `vetDar(sdk, synchronizerId?)` + +## DAR Vetting Utility + +Both modules expose `utils.vetDar`, which loads a local DAR file and uploads it through the SDK: + +```ts +import { TestToken } from '@canton-network/core-splice-codegen' + +await TestToken.utils.vetDar(sdk) +await TestToken.utils.vetDar(sdk, 'global-synchronizer-id') +``` + +Notes: + +- `vetDar` expects local DAR files to exist under `.localnet/dars/`. +- If those files are absent, DAR upload will fail at runtime. + +## Relationship To Token Standard + +`TestToken` command helpers are wired to choice names from `@canton-network/core-token-standard`: + +- transfer-instruction choices +- allocation choices +- transfer/allocation factory choices + +This keeps command generation aligned with Token Standard API semantics while staying strongly typed against DAML templates. + +## License + +Apache-2.0 diff --git a/core/test-token/package.json b/core/splice-codegen/package.json similarity index 85% rename from core/test-token/package.json rename to core/splice-codegen/package.json index 18687f561..5ebb97fce 100644 --- a/core/test-token/package.json +++ b/core/splice-codegen/package.json @@ -1,8 +1,8 @@ { - "name": "@canton-network/core-test-token", - "version": "1.2.0", + "name": "@canton-network/core-splice-codegen", + "version": "1.0.0", "type": "module", - "description": "daml codegen js for test-token package", + "description": "daml codegen js for default packages", "author": "Mateusz PiÄ…tkowski ", "license": "Apache-2.0", "main": "dist/index.cjs", @@ -18,7 +18,7 @@ } }, "scripts": { - "build": "yarn generate:test-token && yarn clean && rollup -c && yarn clean:types-tmp", + "build": "yarn generate:codegen && yarn clean && rollup -c && yarn clean:types-tmp", "dev": "rollup -c -w", "clean:types-tmp": "rm -rf dist/types", "flatpack": "yarn pack --out \"$FLATPACK_OUTDIR\"", @@ -30,7 +30,7 @@ "@canton-network/core-types": "workspace:^", "@canton-network/core-wallet-auth": "workspace:^", "@canton-network/wallet-sdk": "workspace:^", - "@daml/types": "^3.5.1", + "@daml/types": "^3.5.2", "@mojotech/json-type-validation": "^3.1.0", "lodash": "^4.18.1", "openapi-fetch": "^0.17.0", @@ -59,9 +59,9 @@ "repository": { "type": "git", "url": "git+https://github.com/canton-network/wallet.git", - "directory": "core/test-token" + "directory": "core/splice-codegen" }, - "homepage": "https://github.com/canton-network/wallet/tree/main/core/test-token#readme", + "homepage": "https://github.com/canton-network/wallet/tree/main/core/splice-codegen#readme", "bugs": { "url": "https://github.com/canton-network/wallet/issues" } diff --git a/core/test-token/rollup.config.js b/core/splice-codegen/rollup.config.js similarity index 72% rename from core/test-token/rollup.config.js rename to core/splice-codegen/rollup.config.js index d25542a9c..77335ee75 100644 --- a/core/test-token/rollup.config.js +++ b/core/splice-codegen/rollup.config.js @@ -13,7 +13,12 @@ import dts from 'rollup-plugin-dts' const TEST_TOKEN_BASE = path.resolve( import.meta.dirname, - '../../damljs/test-token-v1' + '../../damljs/splice-test-token-v1' +) + +const OTC_TRADE_BASE = path.resolve( + import.meta.dirname, + '../../damljs/splice-token-test-trading-app' ) function buildDamlJsPackagesMap(baseDir) { @@ -47,13 +52,31 @@ function buildDamlJsPackagesMap(baseDir) { return packages } -const DAML_JS_PACKAGES = buildDamlJsPackagesMap(TEST_TOKEN_BASE) const TEST_TOKEN_COMPAT_ALIAS = '@daml.js/test-token-v1' const TEST_TOKEN_CANONICAL_NAME = '@daml.js/splice-test-token-v1-1.0.0' +const OTC_TRADE_COMPAT_ALIAS = '@daml.js/otc-trade' +const OTC_TRADE_CANONICAL_NAME = '@daml.js/splice-token-test-trading-app-1.0.0' + +const DAML_JS_PACKAGES = { + testToken: buildDamlJsPackagesMap(TEST_TOKEN_BASE), + otcTrade: buildDamlJsPackagesMap(OTC_TRADE_BASE), +} + +// Flatten DAML_JS_PACKAGES into a single map for rollup config +const allDamlJsPackages = { + ...DAML_JS_PACKAGES.testToken, + ...DAML_JS_PACKAGES.otcTrade, +} -if (DAML_JS_PACKAGES[TEST_TOKEN_CANONICAL_NAME]) { - DAML_JS_PACKAGES[TEST_TOKEN_COMPAT_ALIAS] = - DAML_JS_PACKAGES[TEST_TOKEN_CANONICAL_NAME] +// Add compatibility aliases +if (DAML_JS_PACKAGES.testToken[TEST_TOKEN_CANONICAL_NAME]) { + allDamlJsPackages[TEST_TOKEN_COMPAT_ALIAS] = + DAML_JS_PACKAGES.testToken[TEST_TOKEN_CANONICAL_NAME] +} + +if (DAML_JS_PACKAGES.otcTrade[OTC_TRADE_CANONICAL_NAME]) { + allDamlJsPackages[OTC_TRADE_COMPAT_ALIAS] = + DAML_JS_PACKAGES.otcTrade[OTC_TRADE_CANONICAL_NAME] } function buildPathsMap(packageDirs) { @@ -93,34 +116,50 @@ function buildAliasEntries(packageDirs) { return entries } -const pathsMap = buildPathsMap(DAML_JS_PACKAGES) -const damlJsAlias = alias({ entries: buildAliasEntries(DAML_JS_PACKAGES) }) +const pathsMap = buildPathsMap(allDamlJsPackages) +const damlJsAlias = alias({ entries: buildAliasEntries(allDamlJsPackages) }) const commonjsPlugin = commonjs({ transformMixedEsModules: true, esmExternals: true, requireReturnsDefault: false, }) +const typescriptPlugin = typescript({ + compilerOptions: { + baseUrl: '.', + paths: pathsMap, + }, +}) + const pkgPath = path.resolve(process.cwd(), 'package.json') const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) -// Collect deps + peerDeps (but not devDeps, or excepted ones) -const exceptions = [ +// Collect deps + peerDeps + transitive deps that should be external +const external = [ + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.peerDependencies || {}), + // Transitive dependencies from damljs packages '@daml/types', '@daml/ledger', '@mojotech/json-type-validation', + // Node built-ins + 'node:fs', + 'node:url', + 'node:path', ] -const external = [ - ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.peerDependencies || {}), -].filter((dep) => !exceptions.includes(dep)) // bundle ESM const codeEsm = { input: 'src/index.ts', output: { file: 'dist/index.js', format: 'es', sourcemap: true }, external, - plugins: [damlJsAlias, json(), commonjsPlugin, nodeResolve(), typescript()], + plugins: [ + damlJsAlias, + json(), + commonjsPlugin, + nodeResolve(), + typescriptPlugin, + ], } // bundle CJS @@ -134,7 +173,13 @@ const codeCjs = { exports: 'named', }, external, - plugins: [damlJsAlias, json(), commonjsPlugin, nodeResolve(), typescript()], + plugins: [ + damlJsAlias, + json(), + commonjsPlugin, + nodeResolve(), + typescriptPlugin, + ], } // bundle for browser @@ -154,7 +199,7 @@ const codeBrowser = { browser: true, // Prefer browser entrypoints preferBuiltins: false, // Do NOT use Node builtins }), - typescript(), + typescriptPlugin, ], } @@ -162,9 +207,10 @@ const codeBrowser = { const types = { input: 'src/index.ts', output: { file: 'dist/index.d.ts', format: 'es' }, + external, plugins: [ dts({ - respectExternal: false, + respectExternal: true, compilerOptions: { baseUrl: '.', paths: pathsMap, diff --git a/core/splice-codegen/src/common.ts b/core/splice-codegen/src/common.ts new file mode 100644 index 000000000..1b006b357 --- /dev/null +++ b/core/splice-codegen/src/common.ts @@ -0,0 +1,47 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { WrappedCommand } from '@canton-network/core-ledger-client-types' +import { SDKInterface } from '@canton-network/wallet-sdk' +import { readFileSync } from 'node:fs' +import path from 'node:path' + +export const vetDarFactory = + (pathToDar: string, packageId: string) => + async ( + sdk: SDKInterface, + synchronizerId?: Parameters[2] + ) => { + const darFile = path.join(import.meta.dirname, pathToDar) + const darBytes = readFileSync(darFile) + + await sdk.ledger.dar.upload(darBytes, packageId, synchronizerId) + } + +export const generateCommand = { + create(templateId: string) { + return ( + createArguments: CreateArgs + ): WrappedCommand<'CreateCommand'> => ({ + CreateCommand: { + templateId, + createArguments, + }, + }) + }, + exercise(templateId: string, choice: string) { + return ( + args: Pick< + WrappedCommand<'ExerciseCommand'>['ExerciseCommand'], + 'contractId' | 'choiceArgument' + > + ): WrappedCommand<'ExerciseCommand'> => ({ + ExerciseCommand: { + templateId, + contractId: args.contractId, + choice, + choiceArgument: args.choiceArgument, + }, + }) + }, +} diff --git a/core/test-token/src/index.ts b/core/splice-codegen/src/index.ts similarity index 59% rename from core/test-token/src/index.ts rename to core/splice-codegen/src/index.ts index 36bb59d83..2fdb9d54f 100644 --- a/core/test-token/src/index.ts +++ b/core/splice-codegen/src/index.ts @@ -1,6 +1,5 @@ // Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -export * from './token' -export * from './commands' -export * from './utils' +export { module as TestToken } from './test-token' +export { module as OTCTrade } from './otc-trade' diff --git a/core/splice-codegen/src/otc-trade/commands.ts b/core/splice-codegen/src/otc-trade/commands.ts new file mode 100644 index 000000000..5030cb601 --- /dev/null +++ b/core/splice-codegen/src/otc-trade/commands.ts @@ -0,0 +1,46 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { generateCommand } from 'src/common' +import { OTCTrade, OTCTradeProposal, TradingApp } from './dar' + +const commands = { + create: { + otcTrade: generateCommand.create( + TradingApp.OTCTrade.templateId + ), + otcTradeProposal: generateCommand.create( + TradingApp.OTCTradeProposal.templateId + ), + }, + + exercise: { + otcTrade: { + settle: generateCommand.exercise( + TradingApp.OTCTrade.templateId, + TradingApp.OTCTrade.OTCTrade_Settle.choiceName + ), + cancel: generateCommand.exercise( + TradingApp.OTCTrade.templateId, + TradingApp.OTCTrade.OTCTrade_Cancel.choiceName + ), + }, + otcTradeProposal: { + accept: generateCommand.exercise( + TradingApp.OTCTradeProposal.templateId, + TradingApp.OTCTradeProposal.OTCTradeProposal_Accept.choiceName + ), + reject: generateCommand.exercise( + TradingApp.OTCTradeProposal.templateId, + TradingApp.OTCTradeProposal.OTCTradeProposal_Reject.choiceName + ), + initiateSettlement: generateCommand.exercise( + TradingApp.OTCTradeProposal.templateId, + TradingApp.OTCTradeProposal.OTCTradeProposal_InitiateSettlement + .choiceName + ), + }, + }, +} + +export default commands diff --git a/core/splice-codegen/src/otc-trade/dar.ts b/core/splice-codegen/src/otc-trade/dar.ts new file mode 100644 index 000000000..3bed42aa2 --- /dev/null +++ b/core/splice-codegen/src/otc-trade/dar.ts @@ -0,0 +1,12 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { Splice } from '@daml.js/otc-trade' + +export { packageId } from '@daml.js/otc-trade' +export const TradingApp = Splice.Testing.Apps.TradingApp + +export type { + OTCTrade, + OTCTradeProposal, +} from '@daml.js/otc-trade/Splice/Testing/Apps/TradingApp' diff --git a/core/splice-codegen/src/otc-trade/index.ts b/core/splice-codegen/src/otc-trade/index.ts new file mode 100644 index 000000000..cfa8242d5 --- /dev/null +++ b/core/splice-codegen/src/otc-trade/index.ts @@ -0,0 +1,13 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import * as DAR from './dar' +import commands from './commands' +import * as utils from './utils' +import { SpliceCodegen } from 'src/types' + +export const module: SpliceCodegen = { + DAR, + commands, + utils, +} diff --git a/core/splice-codegen/src/otc-trade/utils.ts b/core/splice-codegen/src/otc-trade/utils.ts new file mode 100644 index 000000000..e5f5074cf --- /dev/null +++ b/core/splice-codegen/src/otc-trade/utils.ts @@ -0,0 +1,10 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { packageId } from './dar' +import { vetDarFactory } from 'src/common' + +export const vetDar = vetDarFactory( + '../../../../.localnet/dars/splice-otc-trade-v1-1.0.0.dar', + packageId +) diff --git a/core/test-token/src/commands.ts b/core/splice-codegen/src/test-token/commands.ts similarity index 74% rename from core/test-token/src/commands.ts rename to core/splice-codegen/src/test-token/commands.ts index fe097e8cb..c63f4fd1e 100644 --- a/core/test-token/src/commands.ts +++ b/core/splice-codegen/src/test-token/commands.ts @@ -1,55 +1,33 @@ // Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { TestTokenID, TestTokenV1, type Token } from './token' +import { + TestTokenID, + TestTokenV1, + TokenAllocation, + TokenRules, + TokenTransferOffer, + type Token, +} from './dar' import { Allocation, AllocationFactory, - Transfer, TransferFactory, TransferInstruction, - AllocationSpecification, } from '@canton-network/core-token-standard' import { PartyId } from '@canton-network/core-types' import { WrappedCommand } from '@canton-network/core-ledger-client-types' +import { generateCommand } from 'src/common' -const generateCommand = { - create(templateId: string) { - return ( - createArguments: CreateArgs - ): WrappedCommand<'CreateCommand'> => ({ - CreateCommand: { - templateId, - createArguments, - }, - }) - }, - exercise(templateId: string, choice: string) { - return ( - args: Pick< - WrappedCommand<'ExerciseCommand'>['ExerciseCommand'], - 'contractId' | 'choiceArgument' - > - ): WrappedCommand<'ExerciseCommand'> => ({ - ExerciseCommand: { - templateId, - contractId: args.contractId, - choice, - choiceArgument: args.choiceArgument, - }, - }) - }, -} - -export const command = { +const commands = { create: { - transferOffer: generateCommand.create<{ transfer: Transfer }>( + transferOffer: generateCommand.create( TestTokenV1.TokenTransferOffer.templateId ), - allocation: generateCommand.create<{ - allocation: AllocationSpecification - }>(TestTokenV1.TokenAllocation.templateId), - rules: generateCommand.create<{ admin: PartyId }>( + allocation: generateCommand.create( + TestTokenV1.TokenAllocation.templateId + ), + rules: generateCommand.create( TestTokenV1.TokenRules.templateId ), token: (params: { @@ -125,3 +103,5 @@ export const command = { }, }, } + +export default commands diff --git a/core/test-token/src/token.ts b/core/splice-codegen/src/test-token/dar.ts similarity index 53% rename from core/test-token/src/token.ts rename to core/splice-codegen/src/test-token/dar.ts index d3a21deaf..1f030203e 100644 --- a/core/test-token/src/token.ts +++ b/core/splice-codegen/src/test-token/dar.ts @@ -8,8 +8,9 @@ export const TestTokenV1 = Splice.Testing.Tokens.TestTokenV1 export const TestTokenID = 'TestToken' -export type Token = Splice.Testing.Tokens.TestTokenV1.Token -export type TokenAllocation = Splice.Testing.Tokens.TestTokenV1.TokenAllocation -export type TokenRules = Splice.Testing.Tokens.TestTokenV1.TokenRules -export type TokenTransferOffer = - Splice.Testing.Tokens.TestTokenV1.TokenTransferOffer +export type { + Token, + TokenAllocation, + TokenRules, + TokenTransferOffer, +} from '@daml.js/test-token-v1/Splice/Testing/Tokens/TestTokenV1' diff --git a/core/splice-codegen/src/test-token/index.ts b/core/splice-codegen/src/test-token/index.ts new file mode 100644 index 000000000..cfa8242d5 --- /dev/null +++ b/core/splice-codegen/src/test-token/index.ts @@ -0,0 +1,13 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import * as DAR from './dar' +import commands from './commands' +import * as utils from './utils' +import { SpliceCodegen } from 'src/types' + +export const module: SpliceCodegen = { + DAR, + commands, + utils, +} diff --git a/core/splice-codegen/src/test-token/utils.ts b/core/splice-codegen/src/test-token/utils.ts new file mode 100644 index 000000000..3c81bcc2d --- /dev/null +++ b/core/splice-codegen/src/test-token/utils.ts @@ -0,0 +1,10 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { packageId } from './dar' +import { vetDarFactory } from 'src/common' + +export const vetDar = vetDarFactory( + '../../../../.localnet/dars/splice-test-token-v1-1.0.0.dar', + packageId +) diff --git a/core/splice-codegen/src/types.ts b/core/splice-codegen/src/types.ts new file mode 100644 index 000000000..0f4576251 --- /dev/null +++ b/core/splice-codegen/src/types.ts @@ -0,0 +1,31 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { WrappedCommand } from '@canton-network/core-ledger-client-types' +import { vetDarFactory } from './common' + +export type SpliceWrappedCommand = WrappedCommand< + 'CreateCommand' | 'ExerciseCommand' +> + +export type SpliceCommandHandler = (...args: never[]) => SpliceWrappedCommand + +export interface SpliceCommandTree { + [key: string]: SpliceCommandHandler | SpliceCommandTree +} + +export interface SpliceCommands { + create: SpliceCommandTree + exercise: SpliceCommandTree +} + +export interface SpliceCodegen< + DARType extends { packageId: string }, + Commands extends SpliceCommands = SpliceCommands, +> { + DAR: DARType + utils: { + vetDar: ReturnType + } + commands: Commands +} diff --git a/core/splice-codegen/tsconfig.json b/core/splice-codegen/tsconfig.json new file mode 100644 index 000000000..bf03da0a6 --- /dev/null +++ b/core/splice-codegen/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@daml.js/test-token-v1": [ + "../../damljs/splice-test-token-v1/splice-test-token-v1-1.0.0/lib/index.d.ts" + ], + "@daml.js/test-token-v1/*": [ + "../../damljs/splice-test-token-v1/splice-test-token-v1-1.0.0/lib/*" + ], + "@daml.js/otc-trade": [ + "../../damljs/splice-token-test-trading-app/splice-token-test-trading-app-1.0.0/lib/index.d.ts" + ], + "@daml.js/otc-trade/*": [ + "../../damljs/splice-token-test-trading-app/splice-token-test-trading-app-1.0.0/lib/*" + ] + } + }, + "include": ["src"] +} diff --git a/core/test-token/README.md b/core/test-token/README.md deleted file mode 100644 index e09c1ff91..000000000 --- a/core/test-token/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# @canton-network/core-test-token - -TypeScript wrapper package for the Test Token DAML codegen. - -## Exports - -From [src/index.ts](src/index.ts): - -- `TestTokenV1`: shortcut to `Splice.Testing.Tokens.TestTokenV1` -- `packageId`: re-export from `@daml.js/test-token-v1` -- `commands`: command builders for Test Token templates and choices - -## Build - -From the repo root: - -```sh -yarn workspace @canton-network/core-test-token build -``` - -The build produces: - -- ESM: `dist/index.js` -- CJS: `dist/index.cjs` -- Browser ESM: `dist/index.browser.js` -- Types: `dist/index.d.ts` - -## Regenerating DAML Codegen Inputs - -This package depends on generated DAML JS artifacts under -`damljs/test-token-v1`. - -To refresh those artifacts, run: - -```sh -yarn script:generate:test-token -``` - -Then rebuild this package. - -## Usage - -```ts -import { - TestTokenV1, - packageId, - commands, -} from '@canton-network/core-test-token' - -const template = TestTokenV1 -console.log(packageId) - -// Build a create command for TokenRules -const createRules = commands.create.rules({ admin: 'Alice::1220...' }) - -// Build an exercise command for TokenTransferOffer.Accept -const acceptTransfer = commands.exercise.transferOffer.accept({ - contractId: '00a1b2c3d4...', - choiceArgument: {}, -}) -``` - -## Command Helpers - -The `commands` export provides typed helpers that return -`WrappedCommand<'CreateCommand'>` and `WrappedCommand<'ExerciseCommand'>`. - -Available builders: - -- `commands.create.transferOffer` -- `commands.create.allocation` -- `commands.create.rules` -- `commands.exercise.transferOffer.accept` -- `commands.exercise.transferOffer.reject` -- `commands.exercise.transferOffer.withdraw` -- `commands.exercise.transferOffer.update` -- `commands.exercise.allocation.executeTransfer` -- `commands.exercise.allocation.cancel` -- `commands.exercise.allocation.withdraw` -- `commands.exercise.rules.transfer.transfer` -- `commands.exercise.rules.transfer.publicFetch` -- `commands.exercise.rules.allocation.allocate` -- `commands.exercise.rules.allocation.publicFetch` - -Example: - -```ts -import { commands } from '@canton-network/core-test-token' - -const createAllocation = commands.create.allocation({ - allocation: { - // Fill with your AllocationSpecification payload - }, -}) - -const executeTransfer = commands.exercise.allocation.executeTransfer({ - contractId: '00f00d...', - choiceArgument: { - // Fill with Allocation_ExecuteTransfer choice argument - }, -}) -``` - -## License - -Apache-2.0 diff --git a/core/test-token/src/utils.ts b/core/test-token/src/utils.ts deleted file mode 100644 index 0bef5a618..000000000 --- a/core/test-token/src/utils.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -import path from 'node:path' -import { fileURLToPath } from 'node:url' -import { readFileSync } from 'node:fs' -import { SDKInterface } from '@canton-network/wallet-sdk' -import { packageId } from './token' - -export const vetDaml = async (sdk: SDKInterface) => { - const darFile = path.join( - path.dirname(fileURLToPath(import.meta.url)), - '../../../../.localnet/dars/splice-test-token-v1-1.0.0.dar' - ) - const darBytes = readFileSync(darFile) - - await sdk.ledger.dar.upload(darBytes, packageId) -} diff --git a/core/test-token/tsconfig.json b/core/test-token/tsconfig.json deleted file mode 100644 index 56fef3d57..000000000 --- a/core/test-token/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "./src", - "outDir": "./dist", - "moduleResolution": "bundler", - "baseUrl": ".", - "paths": { - "@daml.js/test-token-v1": [ - "../../damljs/test-token-v1/splice-test-token-v1-1.0.0/lib/index.d.ts" - ] - } - }, - "include": ["src"] -} diff --git a/damljs/test-token-v1/.gitignore b/damljs/splice-test-token-v1/.gitignore similarity index 100% rename from damljs/test-token-v1/.gitignore rename to damljs/splice-test-token-v1/.gitignore diff --git a/damljs/splice-token-test-trading-app/.gitignore b/damljs/splice-token-test-trading-app/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/damljs/splice-token-test-trading-app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/examples/test-token-v1-registry/README.md b/examples/test-token-v1-registry/README.md index cd2d5ba02..105f428d7 100644 --- a/examples/test-token-v1-registry/README.md +++ b/examples/test-token-v1-registry/README.md @@ -36,7 +36,7 @@ flowchart LR subgraph DEPS[Package dependencies] direction TB WSDK{{"@canton-network/wallet-sdk"}} - CORETEST{{"@canton-network/core-test-token"}} + CORETEST{{"@canton-network/core-splice-codegen"}} CORESTD{{"@canton-network/core-token-standard"}} end @@ -90,7 +90,6 @@ examples/test-token-v1-registry/ common/ sdk.ts # Wallet SDK bootstrap/auth admin.ts # admin party initialization - vetDaml.ts # dev-only DAR vetting helper getOpenApiPath.ts # OpenAPI source path resolution api/ metadata/ # metadata endpoints + tests diff --git a/examples/test-token-v1-registry/package.json b/examples/test-token-v1-registry/package.json index 5198974dc..80720e9d4 100644 --- a/examples/test-token-v1-registry/package.json +++ b/examples/test-token-v1-registry/package.json @@ -34,7 +34,7 @@ "vitest": "^4.1.8" }, "dependencies": { - "@canton-network/core-test-token": "workspace:^", + "@canton-network/core-splice-codegen": "workspace:^", "@canton-network/core-token-standard": "workspace:^", "@canton-network/core-types": "workspace:^", "@canton-network/wallet-sdk": "workspace:^", diff --git a/examples/test-token-v1-registry/src/api/allocation-instruction/allocationInstruction.test.ts b/examples/test-token-v1-registry/src/api/allocation-instruction/allocationInstruction.test.ts index 9c549c055..169110a27 100644 --- a/examples/test-token-v1-registry/src/api/allocation-instruction/allocationInstruction.test.ts +++ b/examples/test-token-v1-registry/src/api/allocation-instruction/allocationInstruction.test.ts @@ -25,6 +25,26 @@ vi.mock('../../common/operator', () => ({ }, })) +vi.mock('@canton-network/core-splice-codegen', () => ({ + TestToken: { + DAR: { + TestTokenV1: { + TokenRules: { + templateId: 'TestTokenV1:TokenRules', + }, + }, + }, + commands: { + create: { + rules: (payload: { admin: string }) => ({ + templateId: 'TestTokenV1:TokenRules', + payload, + }), + }, + }, + }, +})) + describe('Allocation Instruction', () => { beforeEach(() => { vi.clearAllMocks() diff --git a/examples/test-token-v1-registry/src/api/allocation-instruction/getAllocationFactory.ts b/examples/test-token-v1-registry/src/api/allocation-instruction/getAllocationFactory.ts index 97d7d1dfd..cc8f85dbb 100644 --- a/examples/test-token-v1-registry/src/api/allocation-instruction/getAllocationFactory.ts +++ b/examples/test-token-v1-registry/src/api/allocation-instruction/getAllocationFactory.ts @@ -3,7 +3,7 @@ import sdk from '../../common/sdk' import { operator } from '../../common/operator' -import { command, TestTokenV1 } from '@canton-network/core-test-token' +import { TestToken } from '@canton-network/core-splice-codegen' import { APIError, emptyChoiceContext } from '../common' import { OffLedger } from '@canton-network/core-token-standard' import { TExpressOpenApiRequestHandler } from 'openapi-ts-router/express' @@ -22,7 +22,7 @@ export const getAllocationFactory: TExpressOpenApiRequestHandler< await sdk.ledger.acsReader.readJsContracts({ filterByParty: true, parties: [operator.party], - templateIds: [TestTokenV1.TokenRules.templateId], + templateIds: [TestToken.DAR.TestTokenV1.TokenRules.templateId], }) )[0] @@ -38,7 +38,9 @@ export const getAllocationFactory: TExpressOpenApiRequestHandler< const executionResult = await sdk.ledger .prepare({ partyId: operator.party, - commands: command.create.rules({ admin: operator.party }), + commands: TestToken.commands.create.rules({ + admin: operator.party, + }), }) .sign(operator.keys.privateKey) .execute({ @@ -51,7 +53,7 @@ export const getAllocationFactory: TExpressOpenApiRequestHandler< filterByParty: true, parties: [operator.party], offset: executionResult.completionOffset, - templateIds: [TestTokenV1.TokenRules.templateId], + templateIds: [TestToken.DAR.TestTokenV1.TokenRules.templateId], }) )[0] diff --git a/examples/test-token-v1-registry/src/api/transfer-instruction/getTransferFactory.ts b/examples/test-token-v1-registry/src/api/transfer-instruction/getTransferFactory.ts index 3c4d12e6f..5497656b2 100644 --- a/examples/test-token-v1-registry/src/api/transfer-instruction/getTransferFactory.ts +++ b/examples/test-token-v1-registry/src/api/transfer-instruction/getTransferFactory.ts @@ -1,7 +1,7 @@ // Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { TestTokenV1, command } from '@canton-network/core-test-token' +import { TestToken } from '@canton-network/core-splice-codegen' import sdk from '../../common/sdk' import { operator } from '../../common/operator' import z from 'zod' @@ -55,7 +55,7 @@ export const getTransferFactory: TExpressOpenApiRequestHandler< await sdk.ledger.acsReader.readJsContracts({ filterByParty: true, parties: [operator.party], - templateIds: [TestTokenV1.TokenRules.templateId], + templateIds: [TestToken.DAR.TestTokenV1.TokenRules.templateId], }) )[0] @@ -72,7 +72,9 @@ export const getTransferFactory: TExpressOpenApiRequestHandler< const executionResult = await sdk.ledger .prepare({ partyId: operator.party, - commands: command.create.rules({ admin: operator.party }), + commands: TestToken.commands.create.rules({ + admin: operator.party, + }), }) .sign(operator.keys.privateKey) .execute({ @@ -85,7 +87,7 @@ export const getTransferFactory: TExpressOpenApiRequestHandler< filterByParty: true, parties: [operator.party], offset: executionResult.completionOffset, - templateIds: [TestTokenV1.TokenRules.templateId], + templateIds: [TestToken.DAR.TestTokenV1.TokenRules.templateId], }) )[0] diff --git a/examples/test-token-v1-registry/src/api/transfer-instruction/transferInstruction.test.ts b/examples/test-token-v1-registry/src/api/transfer-instruction/transferInstruction.test.ts index 34f8bc7bf..9620fc11a 100644 --- a/examples/test-token-v1-registry/src/api/transfer-instruction/transferInstruction.test.ts +++ b/examples/test-token-v1-registry/src/api/transfer-instruction/transferInstruction.test.ts @@ -28,6 +28,26 @@ vi.mock('../../common/operator', () => ({ }, })) +vi.mock('@canton-network/core-splice-codegen', () => ({ + TestToken: { + DAR: { + TestTokenV1: { + TokenRules: { + templateId: 'TestTokenV1:TokenRules', + }, + }, + }, + commands: { + create: { + rules: (payload: { admin: string }) => ({ + templateId: 'TestTokenV1:TokenRules', + payload, + }), + }, + }, + }, +})) + describe('Transfer Instruction', () => { beforeEach(() => { vi.clearAllMocks() diff --git a/examples/test-token-v1-registry/src/index.test.ts b/examples/test-token-v1-registry/src/index.test.ts new file mode 100644 index 000000000..e6dbf504a --- /dev/null +++ b/examples/test-token-v1-registry/src/index.test.ts @@ -0,0 +1,73 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { afterEach, describe, expect, it, vi } from 'vitest' + +const use = vi.fn().mockReturnThis() +const listen = vi.fn() +const json = vi.fn() + +const expressFactory = vi.fn(() => ({ + use, + listen, +})) + +const initOperatorParty = vi.fn() +const vetDar = vi.fn() + +vi.mock('express', () => { + const defaultFn = () => expressFactory() + defaultFn.json = json + return { + default: defaultFn, + } +}) + +vi.mock('./common/operator', () => ({ + initOperatorParty, +})) + +vi.mock('./common/sdk', () => ({ + default: {}, +})) + +vi.mock('./api/metadata/index.js', () => ({ + default: 'metadataRouter', +})) + +vi.mock('./api/transfer-instruction/index.js', () => ({ + default: 'transferInstructionRouter', +})) + +vi.mock('./api/allocation/index.js', () => ({ + default: 'allocationRouter', +})) + +vi.mock('./api/allocation-instruction/index.js', () => ({ + default: 'allocationInstructionRouter', +})) + +vi.mock('@canton-network/core-splice-codegen', () => ({ + TestToken: { + utils: { + vetDar, + }, + }, +})) + +describe('entry file', () => { + afterEach(() => { + vi.clearAllMocks() + }) + + it('should initialize the app and start listening', async () => { + await import('./index') + + expect(initOperatorParty).toHaveBeenCalledOnce() + expect(json).toHaveBeenCalledOnce() + expect(use).toHaveBeenCalledTimes(6) + expect(listen).toHaveBeenCalledOnce() + expect(listen).toHaveBeenCalledWith(5634, expect.any(Function)) + expect(vetDar).not.toHaveBeenCalled() + }) +}) diff --git a/examples/test-token-v1-registry/src/index.ts b/examples/test-token-v1-registry/src/index.ts index 6ed3827c4..036010c98 100644 --- a/examples/test-token-v1-registry/src/index.ts +++ b/examples/test-token-v1-registry/src/index.ts @@ -8,7 +8,7 @@ import metadataAPIRouter from './api/metadata/index.js' import transferInstructionAPIRouter from './api/transfer-instruction/index.js' import { initOperatorParty } from './common/operator' import express, { ErrorRequestHandler, Request, Response } from 'express' -import { vetDaml } from '@canton-network/core-test-token' +import { TestToken } from '@canton-network/core-splice-codegen' import sdk from './common/sdk' const app = express() @@ -18,7 +18,7 @@ await initOperatorParty() /** * @customize The registry shouldn't be responsible for vetting daml files. We're doing this for development purposes only. Feel free to remove this when constructing your own token. */ -if (process.env.NODE_ENV === 'development') await vetDaml(sdk) +if (process.env.NODE_ENV === 'development') await TestToken.utils.vetDar(sdk) const errorMiddleware: ErrorRequestHandler = ( error: Error, diff --git a/examples/test-token-v1-registry/vitest.config.ts b/examples/test-token-v1-registry/vitest.config.ts index e843d5a4c..75ff25d3f 100644 --- a/examples/test-token-v1-registry/vitest.config.ts +++ b/examples/test-token-v1-registry/vitest.config.ts @@ -7,13 +7,7 @@ export default defineConfig({ test: { coverage: { include: ['src/**/*.ts'], - exclude: [ - 'src/index.ts', - 'src/router.ts', - 'src/scripts/**', - 'src/api/*/index.ts', - 'src/common/vetDaml.ts', // for dev-mode only - ], + exclude: ['src/api/**/index.ts', 'src/common/sdk.ts'], provider: 'v8', reporter: ['text', 'html', 'lcov', 'json-summary'], thresholds: { diff --git a/package.json b/package.json index ba84934b8..5cb64cb60 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "generate:signing": "yarn workspace @canton-network/core-rpc-generator build && yarn open-rpc-generator generate -c ./rpc-generator-config-signing.json", "generate:grpc": "tsx ./scripts/src/generate-protobufs.ts", "generate:tokenstandard": "tsx ./scripts/src/generate-token-standard.ts", - "generate:test-token": "tsx ./scripts/src/generate-test-token.ts", - "generate:all": "yarn generate:dapp && yarn generate:dapp-remote && yarn generate:user && yarn generate:signing && yarn generate:tokenstandard && yarn generate:test-token && yarn run prettier . --write > /dev/null 2>&1", + "generate:codegen": "tsx ./scripts/src/generate-daml-codegen.ts", + "generate:all": "yarn generate:dapp && yarn generate:dapp-remote && yarn generate:user && yarn generate:signing && yarn generate:tokenstandard && yarn generate:codegen && yarn run prettier . --write > /dev/null 2>&1", "lint": "nx run-many -t lint --parallel", "build:all": "nx run-many -t build --parallel", "build:all:serial": "nx run-many -t build --parallel=1", @@ -67,6 +67,7 @@ "devDependencies": { "@canton-network/core-eslint-config": "workspace:^", "@commitlint/config-conventional": "^20.5.3", + "@daml/types": "^3.5.2", "@eslint/compat": "^2.1.0", "@eslint/js": "^10.0.1", "@nx/eslint": "22.7.6", diff --git a/scripts/src/generate-daml-codegen.ts b/scripts/src/generate-daml-codegen.ts new file mode 100644 index 000000000..f0088ac2a --- /dev/null +++ b/scripts/src/generate-daml-codegen.ts @@ -0,0 +1,94 @@ +// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import * as path from 'path' +import { getArgValue, getRepoRoot, info, warn } from './lib/utils.js' +import { installDPM } from './install-dpm.js' +import { runDamlCodegen } from './lib/daml-codegen.js' +import { existsSync } from 'fs' +import { execSync } from 'child_process' + +const defaultDarFiles = [ + 'splice-test-token-v1-1.0.0', + 'splice-token-test-trading-app-1.0.0', +] + +const codegenOutputDir = (darFile: string) => + darFile.replace(/-\d*\.\d*\.\d*$/, '') + +const repoRoot = getRepoRoot() + +/** + * Installs DPM, ensures localnet DAR artifacts exist, and runs DAML codegen + * for configured DAR packages. + * + * @param --dar-files Optional JSON array of additional DAR file names (without .dar extension) to process. + * Example: `--dar-files='["file-1.0.0","file-2.0.0"]'` + */ +async function main() { + const isCi = process.env.CI === 'true' + const forceCodegen = process.env.FORCE_TEST_TOKEN_CODEGEN === 'true' + + const customDarFiles = getArgValue('dar-files') + + const darFileNames = [ + ...(customDarFiles ? JSON.parse(customDarFiles) : []), + ...defaultDarFiles, + ] as string[] + + const darDir = (file: string) => path.join('damljs', codegenOutputDir(file)) + + if ( + isCi && + !forceCodegen && + darFileNames.every((file) => existsSync(darDir(file))) + ) { + console.log( + info( + `CI detected and generated codegen artifacts already exist. Skipping DPM install and codegen.` + ) + ) + console.log( + info( + 'Set FORCE_TEST_TOKEN_CODEGEN=true to force regeneration in CI.' + ) + ) + return + } + + if (isCi && !forceCodegen) { + console.log( + warn( + `CI detected but codegen is missing; proceeding with DPM install and codegen.` + ) + ) + } + + await installDPM() + + const darsDir = path.join(repoRoot, '.localnet/dars') + + if (!existsSync(darsDir)) { + execSync('yarn script:fetch:localnet', { + cwd: repoRoot, + stdio: 'inherit', + }) + } + + Promise.all( + darFileNames.map(async (file) => { + const options = { + workingDir: darsDir, + darFileName: `${file}.dar`, + outputDir: path.join(repoRoot, darDir(file)), + } + console.info( + 'Producing codegen with following properties:', + options + ) + return await runDamlCodegen(options) + }) + ) +} + +main() diff --git a/scripts/src/generate-test-token.ts b/scripts/src/generate-test-token.ts deleted file mode 100644 index bd841ca97..000000000 --- a/scripts/src/generate-test-token.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -import * as path from 'path' -import { getRepoRoot, info, warn } from './lib/utils.js' -import { installDPM } from './install-dpm.js' -import { runDamlCodegen } from './lib/daml-codegen.js' -import { existsSync } from 'fs' -import { execSync } from 'child_process' - -const repoRoot = getRepoRoot() -const darFileName = 'splice-test-token-v1-1.0.0.dar' -const outputDir = path.join(repoRoot, 'damljs/test-token-v1') -const mainGeneratedPackageDir = path.join( - outputDir, - 'splice-test-token-v1-1.0.0' -) - -/** - * Installs DPM, ensures localnet DAR artifacts exist, and runs DAML codegen - * for the test-token package into damljs/test-token-v1. - */ -async function main() { - const isCi = process.env.CI === 'true' - const forceCodegen = process.env.FORCE_TEST_TOKEN_CODEGEN === 'true' - - if (isCi && !forceCodegen && existsSync(mainGeneratedPackageDir)) { - console.log( - info( - `CI detected and generated test-token artifacts already exist at ${outputDir}. Skipping DPM install and codegen.` - ) - ) - console.log( - info( - 'Set FORCE_TEST_TOKEN_CODEGEN=true to force regeneration in CI.' - ) - ) - return - } - - if (isCi && !forceCodegen) { - console.log( - warn( - `CI detected but ${mainGeneratedPackageDir} is missing; proceeding with DPM install and codegen.` - ) - ) - } - - await installDPM() - - const darsDir = path.join(repoRoot, '.localnet/dars') - - if (!existsSync(darsDir)) { - execSync('yarn script:fetch:localnet', { - cwd: repoRoot, - stdio: 'inherit', - }) - } - - await runDamlCodegen({ - workingDir: darsDir, - darFileName, - outputDir, - }) -} - -main() diff --git a/yarn.lock b/yarn.lock index f0e257bec..6d4a0fe11 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,7 +19,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.29.7": version: 7.29.7 resolution: "@babel/code-frame@npm:7.29.7" dependencies: @@ -30,6 +30,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^8.0.0": + version: 8.0.0 + resolution: "@babel/code-frame@npm:8.0.0" + dependencies: + "@babel/helper-validator-identifier": "npm:^8.0.0" + js-tokens: "npm:^10.0.0" + checksum: 10c0/2ea8614018bcd8c86358ab6aa930508115d2205e5e111f736d355b150453818bdf487850f6dec5ec92a10bf27ba4536f4b3b8ad9204514e43d8d68ff2e542443 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.28.6, @babel/compat-data@npm:^7.29.7": version: 7.29.7 resolution: "@babel/compat-data@npm:7.29.7" @@ -246,6 +256,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^8.0.0": + version: 8.0.4 + resolution: "@babel/helper-validator-identifier@npm:8.0.4" + checksum: 10c0/9d3c639a42b70613016fda026487a3b8056df918cb40221a48ef666a3bd2574475e315ee509c552baef4bef55a627ee8ea530e9af5b376512ab248c37aeab336 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-validator-option@npm:7.29.7" @@ -1266,11 +1283,11 @@ __metadata: linkType: hard "@base-ui/utils@npm:^0.3.1": - version: 0.3.1 - resolution: "@base-ui/utils@npm:0.3.1" + version: 0.3.2 + resolution: "@base-ui/utils@npm:0.3.2" dependencies: "@babel/runtime": "npm:^7.29.2" - "@floating-ui/utils": "npm:^0.2.11" + "@floating-ui/utils": "npm:^0.2.12" reselect: "npm:^5.2.0" use-sync-external-store: "npm:^1.6.0" peerDependencies: @@ -1280,7 +1297,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/4de858c3e2c8a4486a549d51c5e887bba6921e5a7f8db54439ba558feaf1656c3592a873928aee8a1711ee9210be3a65ca43b26713e97f649695ed2fa8c3af2c + checksum: 10c0/b523339f350679915550605e59754b5db9806a41a3b390d6f6adad29fedc0caf084c8ad1bad6bb62a463360593382defb7d3ea941a94404ed9db0142fdae5800 languageName: node linkType: hard @@ -1745,33 +1762,16 @@ __metadata: languageName: unknown linkType: soft -"@canton-network/core-splice-provider@workspace:^, @canton-network/core-splice-provider@workspace:core/splice-provider": +"@canton-network/core-splice-codegen@workspace:^, @canton-network/core-splice-codegen@workspace:core/splice-codegen": version: 0.0.0-use.local - resolution: "@canton-network/core-splice-provider@workspace:core/splice-provider" - dependencies: - "@canton-network/core-rpc-transport": "workspace:^" - "@canton-network/core-types": "workspace:^" - "@canton-network/core-wallet-dapp-remote-rpc-client": "workspace:^" - "@canton-network/core-wallet-dapp-rpc-client": "workspace:^" - "@vitest/browser-playwright": "npm:^4.1.10" - "@vitest/coverage-v8": "npm:^4.1.10" - playwright: "npm:^1.61.1" - tsdown: "npm:^0.22.9" - typescript: "npm:^5.9.3" - vitest: "npm:^4.1.10" - languageName: unknown - linkType: soft - -"@canton-network/core-test-token@workspace:^, @canton-network/core-test-token@workspace:core/test-token": - version: 0.0.0-use.local - resolution: "@canton-network/core-test-token@workspace:core/test-token" + resolution: "@canton-network/core-splice-codegen@workspace:core/splice-codegen" dependencies: "@canton-network/core-ledger-client-types": "workspace:^" "@canton-network/core-token-standard": "workspace:^" "@canton-network/core-types": "workspace:^" "@canton-network/core-wallet-auth": "workspace:^" "@canton-network/wallet-sdk": "workspace:^" - "@daml/types": "npm:^3.5.1" + "@daml/types": "npm:^3.5.2" "@mojotech/json-type-validation": "npm:^3.1.0" "@rollup/plugin-alias": "npm:^5.1.1" "@rollup/plugin-commonjs": "npm:^29.0.3" @@ -1791,6 +1791,23 @@ __metadata: languageName: unknown linkType: soft +"@canton-network/core-splice-provider@workspace:^, @canton-network/core-splice-provider@workspace:core/splice-provider": + version: 0.0.0-use.local + resolution: "@canton-network/core-splice-provider@workspace:core/splice-provider" + dependencies: + "@canton-network/core-rpc-transport": "workspace:^" + "@canton-network/core-types": "workspace:^" + "@canton-network/core-wallet-dapp-remote-rpc-client": "workspace:^" + "@canton-network/core-wallet-dapp-rpc-client": "workspace:^" + "@vitest/browser-playwright": "npm:^4.1.10" + "@vitest/coverage-v8": "npm:^4.1.10" + playwright: "npm:^1.61.1" + tsdown: "npm:^0.22.9" + typescript: "npm:^5.9.3" + vitest: "npm:^4.1.10" + languageName: unknown + linkType: soft + "@canton-network/core-token-standard-service@workspace:^, @canton-network/core-token-standard-service@workspace:core/token-standard-service": version: 0.0.0-use.local resolution: "@canton-network/core-token-standard-service@workspace:core/token-standard-service" @@ -2228,7 +2245,7 @@ __metadata: version: 0.0.0-use.local resolution: "@canton-network/example-test-token-v1-registry@workspace:examples/test-token-v1-registry" dependencies: - "@canton-network/core-test-token": "workspace:^" + "@canton-network/core-splice-codegen": "workspace:^" "@canton-network/core-token-standard": "workspace:^" "@canton-network/core-types": "workspace:^" "@canton-network/wallet-sdk": "workspace:^" @@ -2651,7 +2668,7 @@ __metadata: languageName: node linkType: hard -"@daml/types@npm:^3.5.1, @daml/types@npm:^3.5.2": +"@daml/types@npm:^3.5.2": version: 3.5.2 resolution: "@daml/types@npm:3.5.2" dependencies: @@ -2745,16 +2762,6 @@ __metadata: languageName: node linkType: hard -"@emnapi/core@npm:2.0.0-alpha.3": - version: 2.0.0-alpha.3 - resolution: "@emnapi/core@npm:2.0.0-alpha.3" - dependencies: - "@emnapi/wasi-threads": "npm:2.0.1" - tslib: "npm:^2.4.0" - checksum: 10c0/dfc26f53eb40dab0e316206cabe01e6e98d21ef8a0b820f81ce7e0fa7b4307c94f2a9599c11e6c601ad7bd77e8efb9b7cb9f86dbc3b6237f799405e0cb60c587 - languageName: node - linkType: hard - "@emnapi/core@npm:^1.1.0, @emnapi/core@npm:^1.4.3": version: 1.11.3 resolution: "@emnapi/core@npm:1.11.3" @@ -2792,15 +2799,6 @@ __metadata: languageName: node linkType: hard -"@emnapi/runtime@npm:2.0.0-alpha.3": - version: 2.0.0-alpha.3 - resolution: "@emnapi/runtime@npm:2.0.0-alpha.3" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/c8f6e0ad2f9c0ced8bc156a7ec3ab5fbbd2d3b7147b6a37537f6892131844b969d3aa450749807fc238160b5db61d6160b8066abfce4b2c40acfb1941bb31dd1 - languageName: node - linkType: hard - "@emnapi/runtime@npm:^1.1.0, @emnapi/runtime@npm:^1.4.3": version: 1.11.3 resolution: "@emnapi/runtime@npm:1.11.3" @@ -2846,15 +2844,6 @@ __metadata: languageName: node linkType: hard -"@emnapi/wasi-threads@npm:2.0.1": - version: 2.0.1 - resolution: "@emnapi/wasi-threads@npm:2.0.1" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/5f7bf4cc4f6a1c31ec2084c9321d054f3b3b6c7e89430bb23fc3487d55e7be40f1ff31b2cb9a51721b444d4e8ac1f065b8749606771f6e4e7ccb32bbb709a303 - languageName: node - linkType: hard - "@emotion/babel-plugin@npm:^11.13.5": version: 11.13.5 resolution: "@emotion/babel-plugin@npm:11.13.5" @@ -3397,7 +3386,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.11": +"@floating-ui/utils@npm:^0.2.12": version: 0.2.12 resolution: "@floating-ui/utils@npm:0.2.12" checksum: 10c0/bb910b90d56991a62011afaf5f8e0c4b7fb6dab69403f4dd17fbd6eb25560b28d533dff9791f270b4f459852e9006a1077b5d73cbedb5e34d9424afc6a828314 @@ -4928,7 +4917,7 @@ __metadata: languageName: node linkType: hard -"@napi-rs/wasm-runtime@npm:^1.1.4, @napi-rs/wasm-runtime@npm:^1.1.6, @napi-rs/wasm-runtime@npm:^1.2.0": +"@napi-rs/wasm-runtime@npm:^1.1.4, @napi-rs/wasm-runtime@npm:^1.1.6": version: 1.2.2 resolution: "@napi-rs/wasm-runtime@npm:1.2.2" dependencies: @@ -6375,111 +6364,100 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-android-arm64@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-android-arm64@npm:1.2.1" +"@rolldown/binding-android-arm64@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-android-arm64@npm:1.2.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-darwin-arm64@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-darwin-arm64@npm:1.2.1" +"@rolldown/binding-darwin-arm64@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-darwin-arm64@npm:1.2.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-darwin-x64@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-darwin-x64@npm:1.2.1" +"@rolldown/binding-darwin-x64@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-darwin-x64@npm:1.2.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rolldown/binding-freebsd-x64@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-freebsd-x64@npm:1.2.1" +"@rolldown/binding-freebsd-x64@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-freebsd-x64@npm:1.2.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.1" +"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@rolldown/binding-linux-arm64-gnu@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.1" +"@rolldown/binding-linux-arm64-gnu@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-arm64-musl@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.1" +"@rolldown/binding-linux-arm64-musl@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rolldown/binding-linux-ppc64-gnu@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.1" +"@rolldown/binding-linux-ppc64-gnu@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-s390x-gnu@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.1" +"@rolldown/binding-linux-s390x-gnu@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-x64-gnu@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.1" +"@rolldown/binding-linux-x64-gnu@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-x64-musl@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.1" +"@rolldown/binding-linux-x64-musl@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rolldown/binding-openharmony-arm64@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.1" +"@rolldown/binding-openharmony-arm64@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.2" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-wasm32-wasi@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-wasm32-wasi@npm:1.2.1" - dependencies: - "@emnapi/core": "npm:2.0.0-alpha.3" - "@emnapi/runtime": "npm:2.0.0-alpha.3" - "@napi-rs/wasm-runtime": "npm:^1.2.0" - checksum: 10c0/e5bbfad1862187c60cd9cab802af22c71b2496f89fe73a161931f04594f9db1e09ad7a503a2f980f55a2f6d5a4d2013ad1d17260970ac170a1aa6b9286a41738 - languageName: node - linkType: hard - -"@rolldown/binding-win32-arm64-msvc@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.1" +"@rolldown/binding-win32-arm64-msvc@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-win32-x64-msvc@npm:1.2.1": - version: 1.2.1 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.1" +"@rolldown/binding-win32-x64-msvc@npm:1.2.2": + version: 1.2.2 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -7149,16 +7127,16 @@ __metadata: languageName: node linkType: hard -"@storybook/builder-vite@npm:10.5.5": - version: 10.5.5 - resolution: "@storybook/builder-vite@npm:10.5.5" +"@storybook/builder-vite@npm:10.5.6": + version: 10.5.6 + resolution: "@storybook/builder-vite@npm:10.5.6" dependencies: - "@storybook/csf-plugin": "npm:10.5.5" + "@storybook/csf-plugin": "npm:10.5.6" ts-dedent: "npm:^2.0.0" peerDependencies: - storybook: ^10.5.5 + storybook: ^10.5.6 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/c9c59f4f8d2eeb9d7ee80f039a836ef713f79299a4ddcf2e65532385862d7edda8c89a8098ec44e014f7e36195addfca8566e8e1cbe6838f7f4ecc03812fb72c + checksum: 10c0/ffa255e921d077f17dff56b7fa81e04f5f2ce8ed6e5f1f004a9b9d41095aff90960001da57f7d097c72c82031e0ef1846c9540d958f758d2c3435a21040ec366 languageName: node linkType: hard @@ -7186,15 +7164,15 @@ __metadata: languageName: node linkType: hard -"@storybook/csf-plugin@npm:10.5.5": - version: 10.5.5 - resolution: "@storybook/csf-plugin@npm:10.5.5" +"@storybook/csf-plugin@npm:10.5.6": + version: 10.5.6 + resolution: "@storybook/csf-plugin@npm:10.5.6" dependencies: unplugin: "npm:^2.3.5" peerDependencies: esbuild: "*" rollup: "*" - storybook: ^10.5.5 + storybook: ^10.5.6 vite: "*" webpack: "*" peerDependenciesMeta: @@ -7206,7 +7184,7 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/d837db7bce79322b6e72dfeb203398bf101ec877ceb3abbb56d3f2fc2405159ae7be2c68fb91cb1632efdabb89c8746219c0f4005ab6430239808ee5170cb18d + checksum: 10c0/46e7c24412f9e1f0457f0cc8a1ae1ce54ae865ef1ea953c057abcfcff112720849e80cc4ed0543cb4a72aaad98bde59cd7498552c75ba281f88348a2f2c995b4 languageName: node linkType: hard @@ -7240,15 +7218,15 @@ __metadata: linkType: hard "@storybook/web-components-vite@npm:^10.4.6": - version: 10.5.5 - resolution: "@storybook/web-components-vite@npm:10.5.5" + version: 10.5.6 + resolution: "@storybook/web-components-vite@npm:10.5.6" dependencies: - "@storybook/builder-vite": "npm:10.5.5" - "@storybook/web-components": "npm:10.5.5" + "@storybook/builder-vite": "npm:10.5.6" + "@storybook/web-components": "npm:10.5.6" peerDependencies: - storybook: ^10.5.5 + storybook: ^10.5.6 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/9472165faefcc08727a38f1be834d0e1f9439427d2d0360dfc2eb530791b2837dbbfa3bc05b8e024766cb2d4f532594af98b676427ff474aa76e346dc47c0122 + checksum: 10c0/6d9f3b27dcf50b7c84f8cf08460450f17d50d41714027174dda23ace52e230b2de70158858b099419761a960a9cddfe6e4461bcb8871156697f6a8de027a1d5f languageName: node linkType: hard @@ -7266,17 +7244,17 @@ __metadata: languageName: node linkType: hard -"@storybook/web-components@npm:10.5.5": - version: 10.5.5 - resolution: "@storybook/web-components@npm:10.5.5" +"@storybook/web-components@npm:10.5.6": + version: 10.5.6 + resolution: "@storybook/web-components@npm:10.5.6" dependencies: "@storybook/global": "npm:^5.0.0" tiny-invariant: "npm:^1.3.1" ts-dedent: "npm:^2.0.0" peerDependencies: lit: ^2.0.0 || ^3.0.0 - storybook: ^10.5.5 - checksum: 10c0/af08d12cfb5ccd45fcd41c581f15e889c280deffb1cb1cac38379803475d4e45725042b4a1f4d48516d0e5f88770e12b5526235336cb39b6c351c5bab7be6f95 + storybook: ^10.5.6 + checksum: 10c0/5bec9b29258fc6503075fbe77378e364e32ca5c1d373ce18e9206eba77b0451083010c5b5611a127287a06c304a6ff0eb4205e2c48e7e1783b30d7245ca9cec3 languageName: node linkType: hard @@ -7881,7 +7859,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:^6.9.1": +"@testing-library/jest-dom@npm:6.9.1, @testing-library/jest-dom@npm:^6.9.1": version: 6.9.1 resolution: "@testing-library/jest-dom@npm:6.9.1" dependencies: @@ -7896,11 +7874,11 @@ __metadata: linkType: hard "@testing-library/user-event@npm:^14.6.1": - version: 14.6.1 - resolution: "@testing-library/user-event@npm:14.6.1" + version: 14.6.3 + resolution: "@testing-library/user-event@npm:14.6.3" peerDependencies: "@testing-library/dom": ">=7.21.4" - checksum: 10c0/75fea130a52bf320d35d46ed54f3eec77e71a56911b8b69a3fe29497b0b9947b2dc80d30f04054ad4ce7f577856ae3e5397ea7dff0ef14944d3909784c7a93fe + checksum: 10c0/60c401edcc1b39f98aefd0e236af69c1a0454e3a7b91b92d62e2d654b044c51d39abc4a7ee0f5675566e7246dc5fc5e91af872a49da7e30a5f0e9e52f5a83a82 languageName: node linkType: hard @@ -8512,105 +8490,105 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.65.0" +"@typescript-eslint/eslint-plugin@npm:8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.66.0" dependencies: "@eslint-community/regexpp": "npm:^4.12.2" - "@typescript-eslint/scope-manager": "npm:8.65.0" - "@typescript-eslint/type-utils": "npm:8.65.0" - "@typescript-eslint/utils": "npm:8.65.0" - "@typescript-eslint/visitor-keys": "npm:8.65.0" + "@typescript-eslint/scope-manager": "npm:8.66.0" + "@typescript-eslint/type-utils": "npm:8.66.0" + "@typescript-eslint/utils": "npm:8.66.0" + "@typescript-eslint/visitor-keys": "npm:8.66.0" ignore: "npm:^7.0.5" natural-compare: "npm:^1.4.0" ts-api-utils: "npm:^2.5.0" peerDependencies: - "@typescript-eslint/parser": ^8.65.0 + "@typescript-eslint/parser": ^8.66.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/1d9ddad417b43037c35c91a7c30bfc0015ccc40da57fe9faadae97fbaee6031a539a35265a9933d3bb946f307c397b7a00953806339576a721d619695a972079 + checksum: 10c0/2f8fc6aac7125ae6bebb11f25fd34cbadba4060845a138f819376a5d11c5de380f8117a1fc56e24735e661105e8c3b37f3da50015f840470b7108774b99bd24f languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.65.0, @typescript-eslint/parser@npm:^8.63.0": - version: 8.65.0 - resolution: "@typescript-eslint/parser@npm:8.65.0" +"@typescript-eslint/parser@npm:8.66.0, @typescript-eslint/parser@npm:^8.63.0": + version: 8.66.0 + resolution: "@typescript-eslint/parser@npm:8.66.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.65.0" - "@typescript-eslint/types": "npm:8.65.0" - "@typescript-eslint/typescript-estree": "npm:8.65.0" - "@typescript-eslint/visitor-keys": "npm:8.65.0" + "@typescript-eslint/scope-manager": "npm:8.66.0" + "@typescript-eslint/types": "npm:8.66.0" + "@typescript-eslint/typescript-estree": "npm:8.66.0" + "@typescript-eslint/visitor-keys": "npm:8.66.0" debug: "npm:^4.4.3" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/b3f5333abe5dfb08b53b89c824d045d96d5eb5798fab45eeedfaab72e4ce133a82fb4ebbc1acf79098aac9b08f7acc119fe0edd63ac2f91d80c98f5ca87c41e0 + checksum: 10c0/95efddf190f87bddee46a9662fd7a5c59b9059fd59310c853adb49d0d9378504730f1fc0b55d95b2207964a81756681a9f278a1a339081e4268537696f12c322 languageName: node linkType: hard -"@typescript-eslint/project-service@npm:8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/project-service@npm:8.65.0" +"@typescript-eslint/project-service@npm:8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/project-service@npm:8.66.0" dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.65.0" - "@typescript-eslint/types": "npm:^8.65.0" + "@typescript-eslint/tsconfig-utils": "npm:^8.66.0" + "@typescript-eslint/types": "npm:^8.66.0" debug: "npm:^4.4.3" peerDependencies: typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/56d8f598f1bb6ca892ff79320bd1aa134eefa05cf0bad4932c44518475a8bccf0c9027ae2177b3c1761496c8107236b81dd93f67d09093c2242f07f3f2063c1f + checksum: 10c0/1b8129da708262104691091ac09f67fca2dd877d99090472fd5f0cf86b05755cb3df11d98ed003e775864b9f015c01b429fd5553adbb8a94dd047ff83d4ad6b3 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/scope-manager@npm:8.65.0" +"@typescript-eslint/scope-manager@npm:8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/scope-manager@npm:8.66.0" dependencies: - "@typescript-eslint/types": "npm:8.65.0" - "@typescript-eslint/visitor-keys": "npm:8.65.0" - checksum: 10c0/303bae83a2243e742fcf86bef0b67615dc8915d2dd40268b796e2f49a40057b05de41608846aa362ad77e2d6976ec3cf30f1cdf245c1e39d18fd8ce91ae38c5c + "@typescript-eslint/types": "npm:8.66.0" + "@typescript-eslint/visitor-keys": "npm:8.66.0" + checksum: 10c0/247709b8712295650b8145050c3d566a71ebdca0a10477766cf369f35c9f7fdf7aa62ebb3b3c05fad3ae13c867196c9ff04ede7b1e7b8a6f60acf550207095d4 languageName: node linkType: hard -"@typescript-eslint/tsconfig-utils@npm:8.65.0, @typescript-eslint/tsconfig-utils@npm:^8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.65.0" +"@typescript-eslint/tsconfig-utils@npm:8.66.0, @typescript-eslint/tsconfig-utils@npm:^8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.66.0" peerDependencies: typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/5b897bbba4584ee67c7a0bc0b4b6cbf8db2cb5997d5ab8f07fae692315dd51cabcc7116c609a94a162747dd267118b7a0f1c8fb29d71210ad38549e4b8b6adb1 + checksum: 10c0/1267e1f0adf822062c3917d717f0d1e463e46fdf2d9d0afd6b99b4498f27e63597296cf7ed4a5fe24c3311afb5458d54ccd369d5acee0f51017814384cfd1983 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.65.0, @typescript-eslint/type-utils@npm:^8.0.0": - version: 8.65.0 - resolution: "@typescript-eslint/type-utils@npm:8.65.0" +"@typescript-eslint/type-utils@npm:8.66.0, @typescript-eslint/type-utils@npm:^8.0.0": + version: 8.66.0 + resolution: "@typescript-eslint/type-utils@npm:8.66.0" dependencies: - "@typescript-eslint/types": "npm:8.65.0" - "@typescript-eslint/typescript-estree": "npm:8.65.0" - "@typescript-eslint/utils": "npm:8.65.0" + "@typescript-eslint/types": "npm:8.66.0" + "@typescript-eslint/typescript-estree": "npm:8.66.0" + "@typescript-eslint/utils": "npm:8.66.0" debug: "npm:^4.4.3" ts-api-utils: "npm:^2.5.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/05a1a1283020f63eac3cb6202afd08459531a4522a85ceb0f5789f2902df7c180565f65f217cc780127888b7113b1c8c34aa6bfd7020d568f01a17f290216e9b + checksum: 10c0/a92f8a83264c399583110daef1c8c8a548183aa61dfcda3bbd2f9fe5728235da3039fa4482554d89c6591aaf0f2cc47adb0ad0af54d016273fa879ee06ddfb9c languageName: node linkType: hard -"@typescript-eslint/types@npm:8.65.0, @typescript-eslint/types@npm:^8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/types@npm:8.65.0" - checksum: 10c0/919b6d96111ea26f09c6cb1121fbba915147761be3fbf9c4de5b200faa2891087ebdcfd2f4a1f27a4c6153daeefc7448147c651a074b3ec70440f3f8c1092a81 +"@typescript-eslint/types@npm:8.66.0, @typescript-eslint/types@npm:^8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/types@npm:8.66.0" + checksum: 10c0/cc3f77a9a4e2ee997f0b660e8d31d2e45f3b4a16000f8d4349c85cd50b6a902b71272055116cc01f9cfae063a9d31e8b533e6051334fb345fdf753805014c6b5 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.65.0" +"@typescript-eslint/typescript-estree@npm:8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.66.0" dependencies: - "@typescript-eslint/project-service": "npm:8.65.0" - "@typescript-eslint/tsconfig-utils": "npm:8.65.0" - "@typescript-eslint/types": "npm:8.65.0" - "@typescript-eslint/visitor-keys": "npm:8.65.0" + "@typescript-eslint/project-service": "npm:8.66.0" + "@typescript-eslint/tsconfig-utils": "npm:8.66.0" + "@typescript-eslint/types": "npm:8.66.0" + "@typescript-eslint/visitor-keys": "npm:8.66.0" debug: "npm:^4.4.3" minimatch: "npm:^10.2.2" semver: "npm:^7.7.3" @@ -8618,32 +8596,32 @@ __metadata: ts-api-utils: "npm:^2.5.0" peerDependencies: typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/578ff5247f17865277badfe13362a82ba82c8bb11aaa78323933895e0ba0fc02788ae6aa9bd84bc8287660004a76231341977a3188b399c776b7e713c5054239 + checksum: 10c0/4a755666340ea6f7d329efc402bf0628bf3085c26192b8b346e3641f1b1804c09254a705d0c29b85e2a730258e4675b1678b9f0d95cbbc3b6f5aefb95e6ff67f languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.65.0, @typescript-eslint/utils@npm:^8.0.0": - version: 8.65.0 - resolution: "@typescript-eslint/utils@npm:8.65.0" +"@typescript-eslint/utils@npm:8.66.0, @typescript-eslint/utils@npm:^8.0.0": + version: 8.66.0 + resolution: "@typescript-eslint/utils@npm:8.66.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.9.1" - "@typescript-eslint/scope-manager": "npm:8.65.0" - "@typescript-eslint/types": "npm:8.65.0" - "@typescript-eslint/typescript-estree": "npm:8.65.0" + "@typescript-eslint/scope-manager": "npm:8.66.0" + "@typescript-eslint/types": "npm:8.66.0" + "@typescript-eslint/typescript-estree": "npm:8.66.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/258775532bb23bfeccb7ef25369a62b5fcf48f633af178830113d5aea6d0e968ad67a63b3371206151eb6a8dca0a3381f7efa07958fd8063505e1a53e470a439 + checksum: 10c0/8bce52462ac7c42da7ec3967f1f30c0c9ae527471c6d95de9376a3b4e584bfbcceae7c69cf7df5d081481ccfde5f0682112e05ed4f8704916028a23024e965a0 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.65.0": - version: 8.65.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.65.0" +"@typescript-eslint/visitor-keys@npm:8.66.0": + version: 8.66.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.66.0" dependencies: - "@typescript-eslint/types": "npm:8.65.0" + "@typescript-eslint/types": "npm:8.66.0" eslint-visitor-keys: "npm:^5.0.0" - checksum: 10c0/f50cf2da4077f8eebfd56658ede17dfbf2e39875dc53562f5c1bc6e9835a0b4b00e0e0255e2dc3488234aca1f783d89beb084c417b22027520bf015a7b59ffb8 + checksum: 10c0/12fd739fa3da099145ed21cc3b81fce050a725117639f3e162be51d807b38d553688bdb62b3251c9bb2c9361bfcb4aa68beb0e0e3885620713aa6ede7ce231c7 languageName: node linkType: hard @@ -10139,8 +10117,8 @@ __metadata: linkType: hard "bare-fs@npm:^4.5.5": - version: 4.7.4 - resolution: "bare-fs@npm:4.7.4" + version: 4.8.0 + resolution: "bare-fs@npm:4.8.0" dependencies: bare-events: "npm:^2.5.4" bare-path: "npm:^3.0.0" @@ -10152,7 +10130,7 @@ __metadata: peerDependenciesMeta: bare-buffer: optional: true - checksum: 10c0/c189f8075c7f19142383cda7cb95e85c9a057366e6232f00ce8ad901471291bd2c716d5e480c203c38383c757e64c0388fa5184cfa767dc63c4808e566e16d89 + checksum: 10c0/27e3361b8b2129770e21043ccedd28881d052b38b33d2e909f63484875dc52556aaa514e072ff2172d8372c81447719a9018f28d2f74ce5e1f93cc7aa5df7971 languageName: node linkType: hard @@ -10186,11 +10164,11 @@ __metadata: linkType: hard "bare-url@npm:^2.2.2": - version: 2.4.6 - resolution: "bare-url@npm:2.4.6" + version: 2.4.7 + resolution: "bare-url@npm:2.4.7" dependencies: bare-path: "npm:^3.0.0" - checksum: 10c0/fa93bb9fc643133ca0b38c1431bb2041a7179fd1f5f39d08f303feba018ece752bb823133cfe7849b078c01f907ff31429d915a0ae4c47e03de7d8c42f671354 + checksum: 10c0/f499133ef33715972185f315ea5aa13c4ba0bb82071b205f83727b5fd01532a861473261f876f28cf38212307216a4fb3d9598ce4efcf441af385fd3f7252c95 languageName: node linkType: hard @@ -10202,11 +10180,11 @@ __metadata: linkType: hard "baseline-browser-mapping@npm:^2.10.44": - version: 2.11.11 - resolution: "baseline-browser-mapping@npm:2.11.11" + version: 2.11.12 + resolution: "baseline-browser-mapping@npm:2.11.12" bin: baseline-browser-mapping: dist/cli.cjs - checksum: 10c0/b3eb91b83541a95ea0aa23d34aecefff382cb6b989e88f3411ee1931968cbd4852b874020c788345a082b4090b9643d929e20542438a9c4dac95b74e9632fdb4 + checksum: 10c0/1f4b38379784aba3681b06c304e361c9f03ed6c51205a50c9dd3b5ea87b0e203e6f580384e778374999b000e1b0a0d7351552983aab024d9c4b81b91879c8287 languageName: node linkType: hard @@ -12004,9 +11982,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.5.393": - version: 1.5.399 - resolution: "electron-to-chromium@npm:1.5.399" - checksum: 10c0/5b2ab966e0748d00a2bc2dfd7eee203fe872ce2ca4478eea94f1ceda629172770378128cd6d20be4af8c21874ef250163cd47735e01f38f1182f4312d8c7e78b + version: 1.5.400 + resolution: "electron-to-chromium@npm:1.5.400" + checksum: 10c0/542f30d1aa44d3c6e287e402aeb1636aa134d87222a57d7e6c2a1b4c1279859ed4c425b842cb7e8d09a33f6e4139b7cfa99b2ec8cb18b112f85ce1e76cd26f60 languageName: node linkType: hard @@ -12753,14 +12731,14 @@ __metadata: linkType: hard "express-rate-limit@npm:^8.5.2": - version: 8.6.1 - resolution: "express-rate-limit@npm:8.6.1" + version: 8.6.2 + resolution: "express-rate-limit@npm:8.6.2" dependencies: debug: "npm:^4.4.3" ip-address: "npm:^10.2.0" peerDependencies: express: ">= 4.11" - checksum: 10c0/cb0e30283ef48925d8fe9efce6337a5877bb9a581f32f2594b08303dc075c24f1a52187e403c7f9889888d99eaabd9ac22182d2dadbd0b8acf3725e818131052 + checksum: 10c0/34dba96f7daa01fe9f73a965c0ddaa73bf83d2cb1691ed5e060451ddacebc10fda211a3cf0c34592cf0360bf00d6d9354f3e11ccda7c899705ec1e43383c3144 languageName: node linkType: hard @@ -15645,9 +15623,9 @@ __metadata: linkType: hard "node-releases@npm:^2.0.51": - version: 2.0.51 - resolution: "node-releases@npm:2.0.51" - checksum: 10c0/6cf3fe1f9eabe02ce6de67e9db77b73edc9f5625003791e1f8f239f8e2a851450a5aeb1eff2cc43cfb26312e19b26bfe07626bf428479e6a76f56553fc6148da + version: 2.0.52 + resolution: "node-releases@npm:2.0.52" + checksum: 10c0/2c04530e86035c7f46371e167c49a4d99dfe600c010cb1fe53cd040d34dca314720de749d361ebe467aa4213d6d6de330454a2e1ee0f3e2a25fb6eef9b4ab14e languageName: node linkType: hard @@ -18068,25 +18046,24 @@ __metadata: linkType: hard "rolldown@npm:~1.2.0": - version: 1.2.1 - resolution: "rolldown@npm:1.2.1" + version: 1.2.2 + resolution: "rolldown@npm:1.2.2" dependencies: "@oxc-project/types": "npm:=0.142.0" - "@rolldown/binding-android-arm64": "npm:1.2.1" - "@rolldown/binding-darwin-arm64": "npm:1.2.1" - "@rolldown/binding-darwin-x64": "npm:1.2.1" - "@rolldown/binding-freebsd-x64": "npm:1.2.1" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.1" - "@rolldown/binding-linux-arm64-gnu": "npm:1.2.1" - "@rolldown/binding-linux-arm64-musl": "npm:1.2.1" - "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.1" - "@rolldown/binding-linux-s390x-gnu": "npm:1.2.1" - "@rolldown/binding-linux-x64-gnu": "npm:1.2.1" - "@rolldown/binding-linux-x64-musl": "npm:1.2.1" - "@rolldown/binding-openharmony-arm64": "npm:1.2.1" - "@rolldown/binding-wasm32-wasi": "npm:1.2.1" - "@rolldown/binding-win32-arm64-msvc": "npm:1.2.1" - "@rolldown/binding-win32-x64-msvc": "npm:1.2.1" + "@rolldown/binding-android-arm64": "npm:1.2.2" + "@rolldown/binding-darwin-arm64": "npm:1.2.2" + "@rolldown/binding-darwin-x64": "npm:1.2.2" + "@rolldown/binding-freebsd-x64": "npm:1.2.2" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.2" + "@rolldown/binding-linux-arm64-gnu": "npm:1.2.2" + "@rolldown/binding-linux-arm64-musl": "npm:1.2.2" + "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.2" + "@rolldown/binding-linux-s390x-gnu": "npm:1.2.2" + "@rolldown/binding-linux-x64-gnu": "npm:1.2.2" + "@rolldown/binding-linux-x64-musl": "npm:1.2.2" + "@rolldown/binding-openharmony-arm64": "npm:1.2.2" + "@rolldown/binding-win32-arm64-msvc": "npm:1.2.2" + "@rolldown/binding-win32-x64-msvc": "npm:1.2.2" "@rolldown/pluginutils": "npm:^1.0.0" dependenciesMeta: "@rolldown/binding-android-arm64": @@ -18113,34 +18090,36 @@ __metadata: optional: true "@rolldown/binding-openharmony-arm64": optional: true - "@rolldown/binding-wasm32-wasi": - optional: true "@rolldown/binding-win32-arm64-msvc": optional: true "@rolldown/binding-win32-x64-msvc": optional: true bin: rolldown: ./bin/cli.mjs - checksum: 10c0/d22c80c70d71a36abde7dca7217f66d94cdb5d0c03185205de808d368ab1b8fd5e78ff4db10efc69c5f68a5f9d03d59c8ace848f1f85c4aab79330162a10b3e7 + checksum: 10c0/78a804b9d0947d0569aac5f78ae789b107d097ef94df2ee04b0d89621ca0b62f5336037e6fc1e24209ece2f1d7cbf0d66b27db10b8022684eaf5bea89b9aa97e languageName: node linkType: hard "rollup-plugin-dts@npm:^6.4.1": - version: 6.4.1 - resolution: "rollup-plugin-dts@npm:6.4.1" + version: 6.5.1 + resolution: "rollup-plugin-dts@npm:6.5.1" dependencies: - "@babel/code-frame": "npm:^7.29.0" + "@babel/code-frame": "npm:^8.0.0" "@jridgewell/remapping": "npm:^2.3.5" "@jridgewell/sourcemap-codec": "npm:^1.5.5" convert-source-map: "npm:^2.0.0" magic-string: "npm:^0.30.21" peerDependencies: - rollup: ^3.29.4 || ^4 - typescript: ^4.5 || ^5.0 || ^6.0 + "@typescript/typescript6": ^6 + rollup: ^3 || ^4 + typescript: ^4.5 || ^5 || ^6 || ^7 dependenciesMeta: "@babel/code-frame": optional: true - checksum: 10c0/23d51f4780c5878cb31a45103da961e2e1f81fb830d4b53114931060b58ee431e44c561c1215d253477ad884ba50223dd2586fee704763db9a454cb1c6b97a1d + peerDependenciesMeta: + "@typescript/typescript6": + optional: true + checksum: 10c0/d2d22e3ddbdbf66bcc46519f39451f7a9f3f8744defde5994e7aa35defb1d5a07f126c107c4df65f8181bde96bb7089cc3b57d2d1b65b322961071f947ed306b languageName: node linkType: hard @@ -18431,11 +18410,11 @@ __metadata: linkType: hard "seroval-plugins@npm:^1.5.4": - version: 1.6.0 - resolution: "seroval-plugins@npm:1.6.0" + version: 1.6.2 + resolution: "seroval-plugins@npm:1.6.2" peerDependencies: seroval: ^1.0 - checksum: 10c0/36635a93d270544a840514706a81e4f8d792260101df106e2d16743c0ddb317b012ce9b8bceac755cf4f4191c8f0b55a0031d86bf5e0b86360515d238907cb02 + checksum: 10c0/3e30d9c65fd97f2fd77877b8161066404d1f28bd7b077a552cca7cd63ae19c031d447a593d9f4a886c1403472b0f94cdae9c1a730c22b69a8e4142f50bf9c62f languageName: node linkType: hard @@ -18449,9 +18428,9 @@ __metadata: linkType: hard "seroval@npm:^1.4.2": - version: 1.6.0 - resolution: "seroval@npm:1.6.0" - checksum: 10c0/c7e6079d9507ba9ae21952052eb4f5ae1383f0e586cd71288f81ab63ea708bc7e855c6204b65029091b97e959d5afa735941ff91ae7c596aba9d22fed375685f + version: 1.6.2 + resolution: "seroval@npm:1.6.2" + checksum: 10c0/7beb7e0155e82d8f95471843ab97f9c7dde360f8ae5fac02462f494bb0efe41322f2e7129a3f9f59b0d5ba9cb1f9cc4bb1cc3502b44ca1fc8e82006be8a6c1a6 languageName: node linkType: hard @@ -18921,13 +18900,13 @@ __metadata: linkType: hard "storybook@npm:^10.4.6": - version: 10.5.5 - resolution: "storybook@npm:10.5.5" + version: 10.5.6 + resolution: "storybook@npm:10.5.6" dependencies: "@storybook/global": "npm:^5.0.0" "@storybook/icons": "npm:^2.0.2" "@testing-library/dom": "npm:^10.4.1" - "@testing-library/jest-dom": "npm:^6.9.1" + "@testing-library/jest-dom": "npm:6.9.1" "@testing-library/user-event": "npm:^14.6.1" "@vitest/expect": "npm:3.2.4" "@vitest/spy": "npm:3.2.4" @@ -18954,7 +18933,7 @@ __metadata: optional: true bin: storybook: ./dist/bin/dispatcher.js - checksum: 10c0/f9a373c4a81b85595a76a1d8ea8cbfd428a280c97d39dd4fc987be3d3367a2d460e195b3aa5243ed74cba42860e1d26c2129129b1318fa166a81dadd6cac387d + checksum: 10c0/e5fe04b5fc53760ba6bb57d29211ca56425eb7c2383a2a3dd4a364f8bc28d3896fe7db28424402cc967a1960fc429d3612e4c928ebebf17a59eb9f0cd07c383b languageName: node linkType: hard @@ -19756,17 +19735,17 @@ __metadata: linkType: hard "typescript-eslint@npm:^8.63.0": - version: 8.65.0 - resolution: "typescript-eslint@npm:8.65.0" + version: 8.66.0 + resolution: "typescript-eslint@npm:8.66.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.65.0" - "@typescript-eslint/parser": "npm:8.65.0" - "@typescript-eslint/typescript-estree": "npm:8.65.0" - "@typescript-eslint/utils": "npm:8.65.0" + "@typescript-eslint/eslint-plugin": "npm:8.66.0" + "@typescript-eslint/parser": "npm:8.66.0" + "@typescript-eslint/typescript-estree": "npm:8.66.0" + "@typescript-eslint/utils": "npm:8.66.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/d1f5eede08c6d0d500aa605a1de2a4e721c00e8f56f632581e082aac6d1d2b9d365ce692cf5e0e212ea78271a032c8785e0fc58aee276c7930f92fff6a3358c8 + checksum: 10c0/5a713dd613e56fe11113b2ba8c9f96849dbb0883168e96ff4a800c9a017e974a597c2c99748821e7ade858390711f22fcf5b6b67f14ec5873531d2b1b3968e93 languageName: node linkType: hard @@ -19926,9 +19905,9 @@ __metadata: linkType: hard "undici@npm:^8.4.1": - version: 8.9.0 - resolution: "undici@npm:8.9.0" - checksum: 10c0/e3d9fa35a9aa8360d9f56e66bd372f451ee053e25066a97fd9fab3816267035660f67870c6d709a58a5411551657af78c4475be5b31c113b04f70251309900d0 + version: 8.10.0 + resolution: "undici@npm:8.10.0" + checksum: 10c0/37ae2b1db8f65c3a003504e2040e96887b99f9db16ba07dcf49c37ed8b7f8c72f4452f2d46f52f7c9e49518fe8325e3b5e7e02ac3a2424886bd67d4b62a0ecab languageName: node linkType: hard @@ -20454,6 +20433,7 @@ __metadata: dependencies: "@canton-network/core-eslint-config": "workspace:^" "@commitlint/config-conventional": "npm:^20.5.3" + "@daml/types": "npm:^3.5.2" "@eslint/compat": "npm:^2.1.0" "@eslint/js": "npm:^10.0.1" "@nx/eslint": "npm:22.7.6" @@ -20774,8 +20754,8 @@ __metadata: linkType: hard "ws@npm:^8.0.0, ws@npm:^8.18.0, ws@npm:^8.18.3, ws@npm:^8.19.0, ws@npm:^8.21.0, ws@npm:^8.21.1": - version: 8.21.1 - resolution: "ws@npm:8.21.1" + version: 8.21.2 + resolution: "ws@npm:8.21.2" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -20784,7 +20764,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/c4c6f1d95f6d465262de2037c57c715725d67e078dd49420ede4e19115668aba159cb64d85c5e89c06eb2826be599e62e5095860ad6cc54ff42e8bd7684e1db8 + checksum: 10c0/82d687bbfbccce04e91266ff9911b27c67ca622fd8fbacc6a64d467a43fbd7ecaa3ef6d820b315c060682f901463f57cac01a02b00c4379f49c747ec7da83169 languageName: node linkType: hard