Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
166 changes: 166 additions & 0 deletions core/splice-codegen/README.md
Original file line number Diff line number Diff line change
@@ -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`):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go through this readme and check which sections actually provide value to reader. For example here the same info can be derived by quick look at index. You could either add some descriptions what is TestToken and what is OTCTrade, or just omit it. Build outputs section also provides exactly the same info that dedicated property in package.json - I would skip that.


- `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
Original file line number Diff line number Diff line change
@@ -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 <mateusz.piatkowski@digitalasset.com>",
"license": "Apache-2.0",
"main": "dist/index.cjs",
Expand All @@ -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\"",
Expand All @@ -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",
Expand Down Expand Up @@ -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"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -134,7 +173,13 @@ const codeCjs = {
exports: 'named',
},
external,
plugins: [damlJsAlias, json(), commonjsPlugin, nodeResolve(), typescript()],
plugins: [
damlJsAlias,
json(),
commonjsPlugin,
nodeResolve(),
typescriptPlugin,
],
}

// bundle for browser
Expand All @@ -154,17 +199,18 @@ const codeBrowser = {
browser: true, // Prefer browser entrypoints
preferBuiltins: false, // Do NOT use Node builtins
}),
typescript(),
typescriptPlugin,
],
}

// bundle DTS including types from codegen
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,
Expand Down
Loading