Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
37f0375
feat(example-test-token-v1-registry): create dummy registry server
mateuszpiatkowski-da Jul 10, 2026
fedc3a0
feat: add test token codegen generation
mateuszpiatkowski-da Jul 10, 2026
61cde69
feat(wallet-sdk,core-token-standard): add codegen, create ts interfac…
mateuszpiatkowski-da Jul 11, 2026
4e8bba9
feat(example-test-token-v1-registry): create dummy registry server
mateuszpiatkowski-da Jul 10, 2026
c427480
Merge branch 'mateuszpiatkowski-da/ref-token-create-backend-registry-…
mateuszpiatkowski-da Jul 11, 2026
7d7c974
refactor(wallet-sdk): export plugins, rearrange files
mateuszpiatkowski-da Jul 11, 2026
facaeda
feat(example-test-token-v1-registry): create dummy registry server
mateuszpiatkowski-da Jul 10, 2026
cd32463
Merge branch 'mateuszpiatkowski-da/ref-token-create-backend-registry-…
mateuszpiatkowski-da Jul 11, 2026
7991b87
feat(example-test-token-v1-registry): begin adding api with openapi :…
mateuszpiatkowski-da Jul 13, 2026
ca90ebd
feat(examples-test-token-v1-registry): add metadata api
mateuszpiatkowski-da Jul 13, 2026
74d6876
feat(examples-test-token-v1-registry): establish handler interface
mateuszpiatkowski-da Jul 14, 2026
5c8eeff
feat(examples-test-token-v1-registry): create new api dirs
mateuszpiatkowski-da Jul 14, 2026
f25faea
feat(example-test-token-v1-registry): setup router
mateuszpiatkowski-da Jul 14, 2026
1d50b1c
refactor(example-test-token-v1-registry): improve types
mateuszpiatkowski-da Jul 14, 2026
b02b17e
feat(core-token-standard): export test token package id
mateuszpiatkowski-da Jul 15, 2026
f7ccac9
feat(example-test-token-v1-registry): rearrange files, vet daml, setu…
mateuszpiatkowski-da Jul 15, 2026
f95a8c7
feat(example-test-token-v1-registry): implement get transfer factory
mateuszpiatkowski-da Jul 15, 2026
5e3450e
feat(example-test-token-v1-registry): swap @koa/router with homemade …
mateuszpiatkowski-da Jul 15, 2026
052b04d
feat(example-test-token-v1-registry): finish transfer instruction api
mateuszpiatkowski-da Jul 16, 2026
1413b4d
refactor(example-test-token-v1-registry): move emptychoicecontext
mateuszpiatkowski-da Jul 16, 2026
af7a98b
feat(example-test-token-v1-registry): add allocation api
mateuszpiatkowski-da Jul 16, 2026
eb183f6
feat(example-test-token-v1-registry): add allocation-instruction api
mateuszpiatkowski-da Jul 16, 2026
b31bf14
test(example-test-token-v1-registry): :construction: start working on…
mateuszpiatkowski-da Jul 17, 2026
ff20dd3
test(example-test-token-v1-registry): create tests for allocation & a…
mateuszpiatkowski-da Jul 17, 2026
badbb95
test(example-test-token-v1-registry): add metadata test
mateuszpiatkowski-da Jul 17, 2026
e09422d
test(example-test-token-v1-registry): finish api tests
mateuszpiatkowski-da Jul 17, 2026
d1d3141
test(example-test-token-v1-registry): add admin tests
mateuszpiatkowski-da Jul 17, 2026
65a6409
docs(example-test-token-v1-registry): add api docs
mateuszpiatkowski-da Jul 17, 2026
a029128
docs(example-test-token-v1-registry): add readme contents
mateuszpiatkowski-da Jul 17, 2026
539d047
Merge remote-tracking branch 'origin/main' into mateuszpiatkowski-da/…
mateuszpiatkowski-da Jul 21, 2026
f1aab65
chore: lint fix
mateuszpiatkowski-da Jul 21, 2026
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
12 changes: 6 additions & 6 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"recommendations": [
"arcanis.vscode-zipfs",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"runem.lit-plugin"
]
"recommendations": [
"arcanis.vscode-zipfs",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"runem.lit-plugin"
]
}
4 changes: 4 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ packageExtensions:
dependencies:
'@inquirer/prompts': ^3.0.0
'@open-rpc/schema-utils-js': ^2.0.2
openapicmd@*:
dependencies:
indent-string: ^4.0.0
lodash: '*'
undici-types@*:
dependencies:
'@types/node': '*'
Expand Down
29 changes: 29 additions & 0 deletions core/token-standard/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const DAML_JS_BASE = path.resolve(
'../../damljs/token-standard-models'
)

const TEST_TOKEN_BASE = path.resolve(
import.meta.dirname,
'../../damljs/test-token-v1'
)

const DAML_JS_PACKAGES = {
'@daml.js/token-standard-models-1.0.0': path.join(
DAML_JS_BASE,
Expand All @@ -29,6 +34,30 @@ const DAML_JS_PACKAGES = {
DAML_JS_BASE,
'daml-stdlib-DA-Time-Types-1.0.0'
),
'@daml.js/test-token-v1': path.join(
TEST_TOKEN_BASE,
'splice-test-token-v1-1.0.0'
),
'@daml.js/splice-api-token-allocation-instruction-v1-1.0.0': path.join(
TEST_TOKEN_BASE,
'splice-api-token-allocation-instruction-v1-1.0.0'
),
'@daml.js/splice-api-token-transfer-instruction-v1-1.0.0': path.join(
TEST_TOKEN_BASE,
'splice-api-token-transfer-instruction-v1-1.0.0'
),
'@daml.js/splice-api-token-holding-v1-1.0.0': path.join(
TEST_TOKEN_BASE,
'splice-api-token-holding-v1-1.0.0'
),
'@daml.js/splice-api-token-allocation-v1-1.0.0': path.join(
TEST_TOKEN_BASE,
'splice-api-token-allocation-v1-1.0.0'
),
'@daml.js/splice-api-token-metadata-v1-1.0.0': path.join(
TEST_TOKEN_BASE,
'splice-api-token-metadata-v1-1.0.0'
),
}

function buildPathsMap(packageDirs) {
Expand Down
4 changes: 2 additions & 2 deletions core/token-standard/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

export * from './token-standard-client.js'
export * from './interface-ids.const.js'
export * from './types'

export * from './types.js'
export * from './test-token.js'
export * from '@daml.js/token-standard-models-1.0.0'
9 changes: 9 additions & 0 deletions core/token-standard/src/test-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { Splice, packageId } from '@daml.js/test-token-v1'

export const TestTokenV1 = {
...Splice.Testing.Tokens.TestTokenV1,
packageId,
}
20 changes: 15 additions & 5 deletions core/token-standard/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ export type {

export type {
Transfer,
TransferInstruction,
TransferInstructionView,
TransferInstruction_Accept,
TransferInstruction_Reject,
TransferInstruction_Withdraw,
TransferInstruction_Update,
TransferFactory,
TransferFactoryView,
TransferFactory_PublicFetch,
TransferFactory_Transfer,
Expand All @@ -40,6 +38,12 @@ export type {
TransferInstructionInterface,
} from '@daml.js/token-standard-models-1.0.0/lib/Splice/Api/Token/TransferInstructionV1/module.js'

// Export companion objects as values (needed for accessing choice names at runtime)
export {
TransferInstruction,
TransferFactory,
} from '@daml.js/token-standard-models-1.0.0/lib/Splice/Api/Token/TransferInstructionV1/module.js'

export type {
AllocationFactory_Allocate,
AllocationFactoryView,
Expand All @@ -49,12 +53,16 @@ export type {
AllocationInstructionView,
AllocationInstructionResult,
AllocationInstructionResult_Output,
AllocationFactory,
AllocationFactoryInterface,
AllocationInstruction,
AllocationInstructionInterface,
} from '@daml.js/token-standard-models-1.0.0/lib/Splice/Api/Token/AllocationInstructionV1/module.js'

// Export companion objects as values (needed for accessing choice names at runtime)
export {
AllocationFactory,
AllocationInstruction,
} from '@daml.js/token-standard-models-1.0.0/lib/Splice/Api/Token/AllocationInstructionV1/module.js'

export type {
AllocationRequest,
AllocationRequestView,
Expand All @@ -69,7 +77,6 @@ export type {
SettlementInfo,
Reference,
AllocationView,
Allocation,
AllocationInterface,
Allocation_Withdraw,
Allocation_Cancel,
Expand All @@ -79,6 +86,9 @@ export type {
Allocation_ExecuteTransferResult,
} from '@daml.js/token-standard-models-1.0.0/lib/Splice/Api/Token/AllocationV1/module.js'

// Export companion object as value (needed for accessing choice names at runtime)
export { Allocation } from '@daml.js/token-standard-models-1.0.0/lib/Splice/Api/Token/AllocationV1/module.js'

export type {
ExtraArgs,
Metadata,
Expand Down
3 changes: 3 additions & 0 deletions core/token-standard/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
],
"@daml.js/daml-stdlib-DA-Time-Types-1.0.0/*": [
"../../damljs/token-standard-models/daml-stdlib-DA-Time-Types-1.0.0/*"
],
"@daml.js/test-token-v1": [
"../../damljs/test-token-v1/splice-test-token-v1-1.0.0/lib/index.d.ts"
]
}
},
Expand Down
137 changes: 137 additions & 0 deletions examples/test-token-v1-registry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# @canton-network/example-test-token-v1-registry

Example backend registry implementation for CIP-0056 token flows on Canton.

## Overall Description

This project is a reference implementation of a token registry backend for the Test Token V1 standard. It exposes registry API endpoints for:

- token metadata
- transfer instructions
- allocations
- allocation instructions

Purpose:

- provide a reusable second CIP-0056 test token backend (beyond Amulet) so application tests do not become Amulet-specific
- reduce duplication across teams by offering a shared, easy-to-deploy testing token instead of requiring each team to build a token from scratch
- modernize and harden the earlier prototype by aligning with current Wallet SDK usage and adding verification via automated tests
- provide practical coverage of registry-facing CIP-0056 workflows to complement on-ledger-only token examples

## Getting Started

### Prerequisites

- Node.js 20+
- Yarn 4.x
- dependencies installed at repository root
- local Canton/localnet setup if you want full end-to-end behavior

### Installation

From repository root:

```bash
yarn install
```

Build only this example:

```bash
yarn workspace @canton-network/example-test-token-v1-registry build
```

Run in development mode:

```bash
yarn workspace @canton-network/example-test-token-v1-registry dev
```

The API listens on `http://localhost:3000`.

## Project Structure

### Local Structure Overview

```text
examples/test-token-v1-registry/
src/
index.ts # app startup, admin init, dev vetting hook
router.ts # route prefix to API handler mapping
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
transfer-instruction/ # transfer-instruction endpoints + tests
allocation/ # allocation endpoints + tests
allocation-instruction/ # allocation-instruction endpoints + tests
common.ts # shared API context typing helpers
openapi-ts/ # generated TypeScript types from OpenAPI
scripts/
generateTypes.ts # regenerates openapi-ts bindings
__test__/
mocks.ts # test mocks
vitest.config.ts # node+browser test projects and coverage
tsup.config.ts # build configuration
tsconfig.json
```

## Testing

Run tests:

```bash
yarn workspace @canton-network/example-test-token-v1-registry test
```

Run tests with coverage:

```bash
yarn workspace @canton-network/example-test-token-v1-registry test:coverage
```

Notes:

- tests are discovered under `src/**/*.test.ts`
- both node and browser projects are executed
- coverage thresholds are defined in `vitest.config.ts`

## Development & Contribution Guide

Development loop:

1. Modify API handlers and domain logic in `src/api/**`.
2. If API specs change, regenerate types:

```bash
yarn workspace @canton-network/example-test-token-v1-registry generate:types
```

3. Run tests and coverage.
4. Build before opening a PR.

General contribution guidelines for the monorepo: [Contributing Guide](https://github.com/canton-network/wallet/blob/main/docs/CONTRIBUTING.md)

## 6. License

Apache-2.0

## 7. Additional Resources

- [Wallet Repository](https://github.com/canton-network/wallet)
- [dApp Building Documentation](https://github.com/canton-network/wallet/tree/main/docs/dapp-building)
- [Wallet Integration Guide](https://github.com/canton-network/wallet/tree/main/docs/wallet-integration-guide)
- [CIP Repository (including CIP-0056 context)](https://github.com/canton-foundation/cips)

## 8. Bug Reporting

If you find a bug:

1. Open an issue at: [canton-network/wallet issues](https://github.com/canton-network/wallet/issues)
1. Include reproduction steps, expected behavior, and actual behavior.
1. Attach logs and relevant request/response payloads when possible.

If issue templates are available in the repository, prefer using the most specific template.
66 changes: 66 additions & 0 deletions examples/test-token-v1-registry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"name": "@canton-network/example-test-token-v1-registry",
"version": "1.0.0",
"type": "module",
"description": "Example registry backend app for CIP-0056 token.",
"license": "Apache-2.0",
"author": "Mateusz Piątkowski <mateusz.piatkowski@digitalasset.com>",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
}
},
"scripts": {
"generate:types": "tsx ./src/scripts/generateTypes.ts",
"build": "yarn generate:types && tsup --onSuccess \"tsc\"",
"dev": "yarn generate:types && NODE_ENV=development tsx --watch src/index.ts",
"clean": "tsc -b --clean; rm -rf dist",
"flatpack": "yarn pack --out \"$FLATPACK_OUTDIR\"",
"test": "yarn generate:types && vitest run --project node --project browser",
"test:coverage": "yarn generate:types && vitest run --project node --project browser --coverage"
},
"devDependencies": {
"@types/koa": "^3",
"@types/koa-bodyparser": "^4",
"@types/lodash": "^4.17.24",
"@types/node": "^25.9.3",
"@vitest/browser-playwright": "^4.1.8",
"@vitest/coverage-v8": "^4.1.8",
"openapicmd": "^2.9.2",
"playwright": "^1.60.0",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"vitest": "^4.1.8"
},
"dependencies": {
"@canton-network/core-token-standard": "workspace:^",
"@canton-network/core-types": "workspace:^",
"@canton-network/wallet-sdk": "workspace:^",
"koa": "^3.2.1",
"koa-bodyparser": "^4.4.1",
"openapi-backend": "^5.18.0",
"tsx": "^4.23.0",
"zod": "^4.4.3"
},
"files": [
"dist/**"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/canton-network/wallet.git",
"directory": "examples/test-token-v1-registry"
},
"homepage": "https://github.com/canton-network/wallet/tree/main/examples/test-token-v1-registry#readme",
"bugs": {
"url": "https://github.com/canton-network/wallet/issues"
}
}
Loading
Loading