Token-standard examples: live runs
Three runs are on record: a cn-quickstart LocalNet (below), the Canton Network DevNet (further down, dated 2026-09-22), and the reviewer’s path on a Canton Builder Tool LocalNet (at the end, same day).
The verification clause of the milestone-3 proposal asks for a V1 transfer and
a V2 Account-based transfer/allocation exercised end to end. The five
examples under crates/canton-token/examples
are that exercise, and this file is their output from the most recent run,
kept verbatim so the offsets and update ids can be checked against the
participant that produced them.
Environment
| Date | 2026-09-07 |
| Network | cn-quickstart LocalNet (Splice 0.6.11 images), SV_PROFILE=on |
| Participant | Canton 3.5.7, the App Provider node: gRPC :3901, JSON :3975 |
| Registry | the super-validator’s scan on :5012, reached through a socat forward |
| Instrument | Amulet (Canton Coin), which declares every V1 and V2 token-standard API |
| Sender | the App Provider party (app_provider_quickstart-…) |
| Receiver | the App User party (app_user_quickstart-…) |
| Executor (allocation only) | the super-validator party (sv::…) |
| Authentication | Keycloak OIDC client credentials, as the live tests use |
Every example read its input holdings from the ledger through
canton_token::holdings::spendable — no contract id was supplied by hand — and
submitted with exactly the contracts the registry named for disclosure.
Commands
export CANTON_TEST_ENDPOINT=http://localhost:3901
export CANTON_TEST_TOKEN_URL=http://keycloak.localhost:8082/realms/AppProvider/protocol/openid-connect/token
export CANTON_TEST_CLIENT_ID=app-provider-backend CANTON_TEST_CLIENT_SECRET=…
export CANTON_TOKEN_REGISTRY_URL=http://localhost:5012
export CANTON_TOKEN_SENDER='app_provider_quickstart-…::1220…'
export CANTON_TOKEN_RECEIVER='app_user_quickstart-…::1220…'
export CANTON_TOKEN_EXECUTOR='sv::1220…'
export CANTON_TOKEN_INSTRUMENT=Amulet CANTON_TOKEN_AMOUNT=1.0
cargo run -p canton-token --example v1_transfer
cargo run -p canton-token --example v2_transfer
cargo run -p canton-token --example v2_allocate
And the JSON-only package read that issue #2 asked for, against the same participant with nothing but its JSON port:
CANTON_JSON_ENDPOINT=http://localhost:3975 \
CANTON_TEST_TOKEN_URL=… CANTON_TEST_CLIENT_ID=… CANTON_TEST_CLIENT_SECRET=… \
cargo run -p canton-ledger --example json_packages
Output
v1_transfer — V1 transfer (CIP-56)
2026-09-07T19:52:14Z, exit 0
registry admin: DSO::1220c684772525a9bbf71cfe5669f24944d2ee9cbb34427f3d74ea3a404320168d96
instrument: Canton Coin (CC), 10 decimals
holdings: 1 unlocked holding(s) of Amulet read from the ledger
kind: offer — this will NOT settle until the receiver accepts it
disclosing: 4 contract(s) the registry named
committed 1220a2f8c620e1ec325c2194da01c700a87013a465d03371dc8e3765f7dc6848bbcb at offset 67684 with 6 event(s)
v2_transfer — V2 transfer over accounts (CIP-0112)
2026-09-07T19:52:41Z, exit 0
registry admin: DSO::1220c684772525a9bbf71cfe5669f24944d2ee9cbb34427f3d74ea3a404320168d96
instrument: Canton Coin (CC), 10 decimals
from account: "" / to account: ""
holdings: 1 unlocked holding(s) of Amulet read from the ledger
kind: offer — this will NOT settle until the receiver accepts it
disclosing: 4 contract(s) the registry named
committed 122024fb9a369c0d2556058ed3033c8334ae4800673a73b01af1bc1b2d77b03a7e1c at offset 67690 with 6 event(s)
holdings change on 00f709626156fc630d8e5278b8c9b514e2511609ae117e747a29be08e80ded64e9ca1212203b018402c21cf5e15e4c01c8800e446a1e96456d6a1de77756fa6153207ce301 (node 9): 1 spent, 2 produced, 2 leg(s)
v2_allocate — V2 allocation, three parties (CIP-0112)
2026-09-07T19:52:48Z, exit 0
registry admin: DSO::1220c684772525a9bbf71cfe5669f24944d2ee9cbb34427f3d74ea3a404320168d96
sender: app_provider_quickstart-dimakozoliy-1::12204a2925a78214d3a4c81f3b425f89894a42858b9e8f13a8427c68513232cdf640
receiver: app_user_quickstart-dimakozoliy-1::12209a0cd86271e87116bd1f059b0392dd5a7b09b93681b488082ed8c5a808fc25e3
executor: sv::1220932f0e5664f46da8c8fcc36a6b1f8df822df6d70188d0090878b7e4eed8f2088
holdings: 1 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 122011c124d3a1420d7ce72e172cc8b6934a006eb3dda43e4ea7a9ace9e391756265 at offset 67693 with 6 event(s)
the executor settles this batch with:
settlement id: dvp-1788810771450019
executor: sv::1220932f0e5664f46da8c8fcc36a6b1f8df822df6d70188d0090878b7e4eed8f2088
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00a352050a612e0175c58de115803585cec450a9d3c1cf913d648a8768de587dcfca12122077deccc45c651af83eb4567e5dd30d7f9916991301db8a71e5501a657a685858
created: 00eac6bef2d86eed2ee4eb33362095ee5f1d09471e0341418d9080f8a3206e8fdeca121220e939f334b3bb9c3f71905bfc0d783f4ddfc2531591795dd13cffc7d9f8b14f16
created: 00ba2dedc8f522a97a2a24c64f4854e45f321aa6ae55a408d49e11c328a9dc0a93ca121220eb6dea4ffba2706a8cc14afb6320131e8518003036939a1e734d66b090a0ecba
json_packages — JSON-only package read (issue #2)
2026-09-07T19:51:46Z, exit 0
participant: http://localhost:3975 (JSON Ledger API 3.5.7)
packages known: 63
de2cc2f90eb523414ff54e899951dadd8789a4c07e0f71f6d6c9eaf57d412a54: Registered
What the output shows
| Clause | Evidence |
|---|---|
| V1 transfer settles end to end | v1_transfer: the factory resolved against the registry, four disclosed contracts attached, committed at offset 67684 with 6 events. The kind is offer, so the receiver’s accept completes it — the receiver’s move, from their own credentials |
V2 Account-based transfer | v2_transfer: the same over accounts, committed at offset 67690; events::holdings_changes read the committed transaction back as one holdings change — 1 spent, 2 produced, 2 legs |
| V2 allocation | v2_allocate: sender, receiver and executor are three distinct parties; allocated at offset 67693, 3 contracts created, and the settlement the executor completes is printed with its id. Settling is deliberately not run from the sender’s process |
| Choice context and disclosure | every run lists the contracts the registry named and submitted with them; the transaction would not have interpreted without them |
Amulet is a V2 implementation exercised as one. Whether that satisfies the clause’s words “V2 reference token” is recorded as an open question for the subcommittee in the compatibility matrix, not decided here.
DevNet, 2026-09-22
The same three examples, plus the withdrawal that releases the allocation,
against a validator on the Canton Network DevNet — the network the
proposal’s verification clause names. Every submission was direct: the
receiving party holds a transfer pre-approval, so both transfers settled on
submission with no accept step, which is the clause’s “settles end to end”
taken literally.
Environment
| Date | 2026-09-22, 07:32–07:34 UTC |
| Network | Canton Network DevNet, synchronizer global-domain::1220be58… |
| Participant | nodejumper-dev-1, Canton 3.5.17, Splice validator 0.8.1 (Nodejumper’s node) |
| Ledger API | gRPC over TLS on :443; JSON Ledger API over HTTPS |
| Authentication | Keycloak, realm canton-devnet: a user token with actAs on the sender party and nothing else |
| Registry | the public DevNet Scan of SV-1, https://scan.sv-1.dev.global.canton.network.sync.global, unauthenticated |
| Instrument | Amulet (Canton Coin); the DevNet registry declares all ten V1 and V2 APIs |
| Sender | 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd…, a wallet user on that node, funded by a tap |
| Receiver and executor | nodejumper-dev-1::1220a5cd…, the validator’s own party |
| Amount | 1 CC per operation |
The registry’s OpenAPI documents at Splice 0.8.1 were diffed against the
vendored 0.6.11 copies before the run: six of seven are byte-identical and
token-metadata-v1 differs only by the additive accountInputFieldsToShow
field, which Instrument already carries.
Commands
export CANTON_TEST_ENDPOINT=https://ledger-grpc.validator.devnet.canton.nodejumper.io
export CANTON_TEST_JSON_ENDPOINT=https://ledger-api.validator.devnet.canton.nodejumper.io
export CANTON_TOKEN_REGISTRY_URL=https://scan.sv-1.dev.global.canton.network.sync.global
export CANTON_TOKEN=… # a bearer token for the sender's user
export CANTON_TOKEN_SENDER='8f2bb33b-…::1220a5cd…'
export CANTON_TOKEN_RECEIVER='nodejumper-dev-1::1220a5cd…'
export CANTON_TOKEN_EXECUTOR='nodejumper-dev-1::1220a5cd…'
export CANTON_TOKEN_INSTRUMENT=Amulet CANTON_TOKEN_AMOUNT=1.0
cargo run -p canton-token --example v1_transfer
cargo run -p canton-token --example v2_transfer
cargo run -p canton-token --example v2_allocate
cargo run -p canton-token --example v2_withdraw_allocation
Each was run first with CANTON_TOKEN_DRY_RUN=1 — the command built against
the real registry, with its context and disclosures, and not submitted — and
then for real.
Output
v1_transfer — V1 transfer (CIP-56), direct
2026-09-22T07:32:26Z, exit 0
registry admin: DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a
instrument: Canton Coin (CC), 10 decimals
holdings: 1 unlocked holding(s) of Amulet read from the ledger
kind: direct — completes on submission
disclosing: 6 contract(s) the registry named
committed 12203d9608d50269325b406975fc6445c1956acd845dc30185bab22db21b3979fb3d at offset 3316298 with 7 event(s)
v2_transfer — V2 transfer over accounts (CIP-0112), direct
2026-09-22T07:32:33Z, exit 0
registry admin: DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a
instrument: Canton Coin (CC), 10 decimals
from account: "" / to account: ""
holdings: 1 unlocked holding(s) of Amulet read from the ledger
kind: direct — completes on submission
disclosing: 6 contract(s) the registry named
committed 12202e8ddcd542ff100bd16850a6d2b97f4cced6cf25246ea1c55fb77baf2fe5579e at offset 3316304 with 7 event(s)
holdings change on 00435bc9becd27689198d8123677d28c1b23061da6b0716fc3c24e02deb657c3cbca1212206d0cde3b136ecb322fc15ff0c110882c11910cdd31009451eacdb5cb72434ecb (node 11): 1 spent, 1 produced, 1 leg(s)
holdings change on 00435bc9becd27689198d8123677d28c1b23061da6b0716fc3c24e02deb657c3cbca1212206d0cde3b136ecb322fc15ff0c110882c11910cdd31009451eacdb5cb72434ecb (node 12): 0 spent, 1 produced, 1 leg(s)
v2_allocate — V2 allocation (CIP-0112)
2026-09-22T07:32:44Z, exit 0
registry admin: DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a
sender: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
receiver: nodejumper-dev-1::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
executor: nodejumper-dev-1::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
holdings: 1 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 12201e70b86ba0ef478fc6738c62d85d13a38e2df1318671db6b0ae560e751afe3fd at offset 3316319 with 6 event(s)
the executor settles this batch with:
settlement id: dvp-1790062365710383
executor: nodejumper-dev-1::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00f536ec3917d4ab54acefc4aad06ad72cfd9690fda1c157468475041016c63b72ca121220776cab3d3e2c5bea1d1fe570310fb30ec1483b00a1d50b1825c5716d2eb49af9
created: 009badac1d7fc8a59777ae65c71d9d319a16598b20ec4321c9b148cd7c2cfc57a8ca12122086e787c4fc08e546ebe24d6d88f9879382ede8fa443a8d44ebe8b8fe7897f925
created: 00594cb3a8b1a5d3ecdbfca3c40a20c37eb5e3bf748d4ebd75235a0ffbdb0ae555ca121220ca0f4d05081cc81706f2df0879af716cc2db3460e358f70dcacc8c7887334b7e
v2_withdraw_allocation — V2 allocation withdrawn by the sender
2026-09-22T07:33:39Z, exit 0
sender: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
allocations: 1 active
00594cb3a8b1a5d3ecdbfca3c40a20c37eb5e3bf748d4ebd75235a0ffbdb0ae555ca121220ca0f4d05081cc81706f2df0879af716cc2db3460e358f70dcacc8c7887334b7e
settlement dvp-1790062365710383 by nodejumper-dev-1::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd, 1 holding(s) reserved
withdrawing 00594cb3a8b1a5d3 (settlement dvp-1790062365710383): disclosing 4 contract(s) the registry named
withdrawn: 12209b5d69f163eca284c4f2c04cfcbb030de8792012a5e37c3c8b64294f3a7a51a3 at offset 3316364 with 7 event(s)
Read back from the participant by update id
Every update id above was read back from the node over the JSON Ledger API
(POST /v2/updates/update-by-id) after the run. The record times are the
synchronizer’s.
| Update id | Offset | Record time | Events visible to the sender |
|---|---|---|---|
12203d9608d50269325b… | 3316298 | 2026-09-22T07:32:29.748296Z | 2 |
12202e8ddcd542ff100b… | 3316304 | 2026-09-22T07:32:34.873070Z | 2 |
12201e70b86ba0ef478f… | 3316319 | 2026-09-22T07:32:47.179492Z | 4 |
12209b5d69f163eca284… | 3316364 | 2026-09-22T07:33:42.266115Z | 3 |
The public Scan’s transaction API answers 403 to unauthenticated callers on DevNet, so the ids are verifiable from any DevNet participant rather than from a browser. The sender’s holdings afterwards: 837.2655239056 CC and the 1 CC the withdrawal released, both unlocked — 840 minus the two transfers, nothing left reserved.
Executor settlement, the same day
The allocation above was withdrawn, not settled: the executor is the
validator’s party and this run holds no token for it. settle_batch — the
executor’s move, and the proposal’s “allocation/executor settlement” — was
then exercised with the sender as executor, in two attempts that together say
what a V2 settlement requires.
First attempt, refused by the settlement factory. An allocation naming the
sender as executor, one leg from the sender to the validator’s party.
Amulet’s SettlementFactory_SettleBatch refused it at interpretation:
executor: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
allocations: 1 naming it as executor
settlement dvp-1790063359274031: 1 allocation(s), 1 leg(s)
leg leg-1: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd -> nodejumper-dev-1::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd : 1.0000000000 Amulet
disclosing 3 contract(s) the registry named
Error: Status(Status { code: FailedPrecondition, message: "DAML_FAILURE(9,5085fbf8): Interpretation error: Error: User failure: UNHANDLED_EXCEPTION/DA.Exception.GeneralError:GeneralError (error category 9): 'missing authorizations' is not equal to 'empty set'.\nmissing authorizations: Set [(Account {owner = Some 'nodejumper-dev-1::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd', provider = None, id = \"\"},TransferLegSide {transferLegId = \"leg-1\", side = ReceiverSide, otherside = Account {owner = Some '8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd...", details: … }
That is the standard, not a bug: a V2 leg needs both sides authorised — the
receiver consents with a ReceiverSide allocation of its own — and a
transfer pre-approval does not stand in for it. This allocation was withdrawn
(update 1220f4a7…, offset 3317173).
Second attempt, settled. A leg whose sender, receiver and executor are the
same party, so one allocation carries both sides and one token can execute.
Degenerate as a delivery-versus-payment, but it drives the whole path: the
allocation factory, the settlement factory’s context and disclosures, and
settle_batch committing on the DevNet synchronizer.
v2_allocate — both sides of the leg in one allocation
2026-09-22T07:50:32Z, exit 0
receiver: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
receiver = sender: authorising both sides of the leg in this allocation
allocated: 1220a959f224d586e432b0e7684cd04b6d204356b33f6ecf3d334d0ecbbb8e59ea5b at offset 3317197 with 2 event(s)
settlement id: dvp-1790063434475117
v2_settle — the executor settles the batch
2026-09-22T07:50:54Z, exit 0
executor: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd
allocations: 1 naming it as executor
settlement dvp-1790063434475117: 1 allocation(s), 1 leg(s)
leg leg-1: 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd -> 8f2bb33b-699f-440e-a861-508ee6a0472d::1220a5cd222348403b3db750ba80ddbd0c3f18a5692b425273d150c1efff5ceb63bd : 1.0000000000 Amulet
disclosing 2 contract(s) the registry named
settled: 1220b829f7b412aedd5215d77f006b4d6fdd54696cfaf21fe1093c18754327299d69 at offset 3317221 with 4 event(s)
Read back by update id:
| Update id | Offset | Record time | Events visible to the sender |
|---|---|---|---|
1220424177cbc89173b0… | 3317129 | 2026-09-22T07:49:20.440389Z | 4 |
1220f4a77863cb1ad1ea… | 3317173 | 2026-09-22T07:50:15.185034Z | 3 |
1220a959f224d586e432… | 3317197 | 2026-09-22T07:50:35.177075Z | 1 |
1220b829f7b412aedd52… | 3317221 | 2026-09-22T07:50:57.874686Z | 1 |
The sender’s holdings afterwards: one unlocked holding of 838.2655239056 CC — 840 minus the two transfers to the validator, the settled coin back with its owner, nothing reserved.
Live suites against the same node
With CANTON_TEST_REQUIRE_LIVE=1, so a suite that could not reach the node
fails rather than skips:
canton-tokenlive suite against the DevNet registry: 5 passed — the registry describes itself and its instruments as the standard says, and paging works against a real Scan.canton-ledgerlive suite, the subset a node without the test DAR can run: 6 passed — version and health over gRPC, version and ledger end over JSON, the JSON-only package read (288 packages), the JSON party reads (the participant id, the sender’s own party), a bad token is an HTTP error.
The submission-based ledger and interactive-submission suites need the
quickstart-licensing package on the participant and were not run here;
they run against the LocalNet above.
What the run shows against the clause
| Clause | Evidence |
|---|---|
| A V1 transfer settles end to end on DevNet | committed at offset 3316298, kind direct, read back with record time 07:32:29 UTC |
A V2 Account-based transfer/allocation exercised against Canton Coin’s V2 path on DevNet | transfer at 3316304 with the holdings change parsed from the committed transaction; allocation at 3316319 naming the validator as executor, withdrawn at 3316364; allocation at 3317197 settled by its executor at 3317221 |
| Allocation/executor settlement | settle_batch committed through Amulet’s settlement factory at 3317221, after the factory had refused a one-sided leg — the refusal is on record above |
| Choice context and disclosure, against a production registry | six disclosed contracts per transfer, two per allocation, four per withdrawal, all named by the DevNet Scan |
The clause names two V2 targets, joined by “and”: the V2 reference token,
and Canton Coin’s V2 path on DevNet. This run covers the second. The first is
not covered here: the reference token is TestTokenV2 from Splice’s
splice-token-standard-v2-test package, which Splice exercises by Daml script
against a simulated registry; it has no deployment on DevNet, and the
separate V2 DevNet that once hosted it is retired. Closing that half means
either standing the reference token up ourselves — its DAR on a participant,
with a registry for it — or the subcommittee agreeing that the deployed V2
implementation stands in for a reference token that is not deployed anywhere.
The reviewer’s path: Canton Builder Tool, 2026-09-22
The “How to verify” steps of the milestone comment, run verbatim from a fresh
clone of the branch (git clone, then the commands as written) against a
Canton Builder Tool
LocalNet — the environment the Foundation’s reviewer used for the earlier
milestones. Nothing beyond canton builder start, one tap in the App Provider
wallet, and the commands.
| LocalNet | Canton Builder Tool, Splice 0.6.11 images, Canton 3.5.7; auth self-signed (HS256 tokens from canton builder token, whose user holds ParticipantAdmin) |
| Registry | the LocalNet’s own Scan, http://scan.localhost:4000 |
| Party | app_provider_builder-localnet-1::122050a3…, sender, receiver and executor at once (kind: self) |
| External signing | the built-in Ping template every participant ships, created by the freshly onboarded external party |
| PQS | Scribe 3.5.4 from tools/pqs/compose.yaml, reading as the same token, after wait-ready.sh |
### step 2: cargo test --workspace --all-features
test lower::tests::a_daml_name_rust_cannot_spell_is_skipped_not_panicked_on ... ok
passed: 600 failed: 0
### step 3: conformance
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 5 tests
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 51 tests
test result: ok. 51 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
capabilities: 51 gaps: 0
### step 4: external signing
committed 122070b591b0a0b519fa1d06c4809003ae6f0d063b48f72186ba309276041f4f31e1 at offset 303 with 1 event(s)
test external_commands__prepare_sign_execute_commits_a_transaction ... ok
test signing__an_external_party_is_onboarded_by_signing_its_own_topology ... ok
rejected as expected: grpc status Client specified an invalid argument: FAILED_TO_EXECUTE_TRANSACTION(8,bbc5eeef): The participant failed to execute the transaction: Received 0 valid signatures from d
test signing__a_signature_from_another_key_is_rejected ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.91s
### step 5: json_packages
participant: http://localhost:3975 (JSON Ledger API 3.5.7)
packages known: 60
de2cc2f90eb523414ff54e899951dadd8789a4c07e0f71f6d6c9eaf57d412a54: Registered
### step 6: token standard
test the_registry_says_who_administers_its_instruments ... ok
test paging_through_instruments_works_against_a_real_registry ... ok
test the_registry_declares_which_token_standard_versions_it_serves ... ok
test an_instrument_this_registry_does_not_issue_is_none_rather_than_an_error ... ok
test the_instruments_decode_as_the_standard_describes_them ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
--- v1_transfer
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
instrument: Amulet (AMT), 10 decimals
holdings: 1 unlocked holding(s) of Amulet read from the ledger
kind: self — sender and receiver match
disclosing: 4 contract(s) the registry named
committed 1220eeabaf4c53d837e1ee9ecd24e69e6c480b1c8e26763f3bd7f83685277d520705 at offset 311 with 5 event(s)
exit=0
--- v2_transfer
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
instrument: Amulet (AMT), 10 decimals
from account: "" / to account: ""
holdings: 2 unlocked holding(s) of Amulet read from the ledger
kind: self — sender and receiver match
disclosing: 4 contract(s) the registry named
committed 122021d543f64f15dca59f5d0db3c6a923b622825b904ea06e266c9e7e91dfcdbed8 at offset 314 with 6 event(s)
holdings change on 00bb34aac538c58ba3ca4a08d848d709d17dec3a0f3cf2ec32c124d01db1c2d357ca121220423f5b875fe0a0747bf01aaef96096929245507ad6b089128fd66028710e9af6 (node 12): 2 spent, 2 produced, 2 leg(s)
exit=0
--- v2_allocate
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver = sender: authorising both sides of the leg in this allocation
holdings: 2 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 1220ea0fae9279d586d46b78a5382a195af5aa315ee8168a26cf1c3b8a6183aa7a1b at offset 317 with 2 event(s)
the executor settles this batch with:
settlement id: dvp-1790073600615421
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00b55f1fb85f23d86f6816e6ecbb1ca75bd35b052497575d1273a26c0ededaec3eca121220332df3d5975bcf7c4f8fceca7abeed58adf50c249a71cd342b4d3fa27700803e
exit=0
--- v2_withdraw_allocation
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
allocations: 1 active
00b55f1fb85f23d86f6816e6ecbb1ca75bd35b052497575d1273a26c0ededaec3eca121220332df3d5975bcf7c4f8fceca7abeed58adf50c249a71cd342b4d3fa27700803e
settlement dvp-1790073600615421 by app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e, 0 holding(s) reserved
withdrawing 00b55f1fb85f23d8 (settlement dvp-1790073600615421): disclosing 0 contract(s) the registry named
withdrawn: 1220b6c66e3c202d0ac7b55fa693c1e95e5486302408c41422e73cbe9d9eafa4190b at offset 320 with 2 event(s)
exit=0
--- v2_allocate
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver = sender: authorising both sides of the leg in this allocation
holdings: 2 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 12206f7aeb40c08e1dbf9f512c8dfaec2ee02c5648b0309478834984f56b500189a6 at offset 323 with 2 event(s)
the executor settles this batch with:
settlement id: dvp-1790073604041114
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00a85b1e5b537e01969d0f19cad1355c584cbdb341594c7f8b91538d22be0f0a88ca121220c6e240b34c502e153e2da2d363c2b6ed423bd8634284ee731eb3890f79426ad6
exit=0
--- v2_settle
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
allocations: 1 naming it as executor
settlement dvp-1790073604041114: 1 allocation(s), 1 leg(s)
leg leg-1: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e -> app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e : 1.0000000000 Amulet
disclosing 2 contract(s) the registry named
settled: 12206f9fa56dbc7208b1534bfed792427d3d7314cb22db4bbaa1bf2f5ba69aeb9092 at offset 326 with 4 event(s)
exit=0
### step 7: pqs
Container pqs-scribe-1 Started
pqs ready at offset 326
test a_refused_connection_is_not_retried_forever ... ok
test pqs_reports_how_far_it_has_ingested ... ok
test an_ordered_comparison_is_a_statement_postgres_accepts ... ok
active Amulet: 2
test a_contract_read_from_postgres_is_the_generated_type ... ok
test a_contract_is_found_by_id ... ok
test containment_and_party_columns_work_against_the_real_schema ... ok
test the_acs_can_be_read_as_of_an_offset ... ok
test a_payload_predicate_filters_in_the_database ... ok
test a_connection_the_store_closes_is_replaced_on_the_next_read ... ok
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.34s
Network pqs_default Removed
Every step passed as written. Step 4 is the one to read closely: the
onboarded party committed a create and the participant refused a signature
from another key. An earlier run of the same day reported the same three
tests green while two of them had quietly returned for want of an application
package; that silent return is gone, which is what CANTON_TEST_REQUIRE_LIVE
exists to guarantee.
The reviewer’s path at v0.3.1: Canton Builder Tool, 2026-09-29
The “How to verify” steps of the Milestone 3a comment on the tracking issue,
run verbatim from a fresh clone at the v0.3.1 tag (a32f6f3) against the same
Canton Builder Tool LocalNet as above (Canton 3.5.7), with the App Provider
party as sender, receiver and executor. Step numbers are the comment’s. Step 1
is the cargo add of the published crates into a new project; the target
directory was warm, hence the short build time.
### 3a verbatim run 2026-09-29T13:13:56Z
### step 1
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Adding canton v0.3.1 to dependencies
Adding canton-token v0.3.1 to dependencies
Adding canton-signer v0.3.1 to dependencies
Adding canton-pqs v0.3.1 to dependencies
Adding canton-splice-api-token-holding-v2 v0.3.1 to dependencies
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.14s
exit=0
versions: 21 v0.3.1
### step 2
at v0.3.1 a32f6f3
test lower::tests::a_daml_name_rust_cannot_spell_is_skipped_not_panicked_on ... ok
tests passed: 632 failed: 0
conformance: test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
conformance: test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
conformance: test result: ok. 51 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
conformance: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
conformance: test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
capabilities: 51 gaps: 0
### step 3
test external_commands__prepare_sign_execute_commits_a_transaction ... ok
test signing__a_signature_from_another_key_is_rejected ... ok
test signing__an_external_party_is_onboarded_by_signing_its_own_topology ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.68s
### step 4 (no tap: the party already holds Amulet)
party: app_provider_builder-localnet-1::…
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
--- v1_transfer
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
instrument: Amulet (AMT), 10 decimals
holdings: 1 unlocked holding(s) of Amulet read from the ledger
kind: self — sender and receiver match
disclosing: 4 contract(s) the registry named
committed 12207e951759258c98f480ae38296a36d925aeae3afbb7c6386b155c5ca1ec44787e at offset 12769 with 5 event(s)
--- v2_transfer
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
instrument: Amulet (AMT), 10 decimals
from account: "" / to account: ""
holdings: 2 unlocked holding(s) of Amulet read from the ledger
kind: self — sender and receiver match
disclosing: 4 contract(s) the registry named
committed 122051d653917109557bf71b2dc07d0d9e6024128508690813823cc7d94bb192c459 at offset 12772 with 6 event(s)
holdings change on 00fc1b5219b7b8dba23791792ef51f06a2795e57cf44115214ee00fedc05a08064ca121220ff76501f926ceec61b4227ab711abcd5f43499dc73511028817
--- v2_allocate
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver = sender: authorising both sides of the leg in this allocation
holdings: 2 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 1220a5da7fbc468fe732712ea20ae879fd79855be0c5d6991935acceb551cdef405d at offset 12775 with 2 event(s)
the executor settles this batch with:
settlement id: dvp-1790687799143875
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00b77ba11301519e41621c50427bba4def60271951187d334af92780b84121d888ca121220826e55e1acfe364e1ee38e2e362b340a324f1c15a4666d75bee860d
--- v2_withdraw_allocation
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
allocations: 1 active
00b77ba11301519e41621c50427bba4def60271951187d334af92780b84121d888ca121220826e55e1acfe364e1ee38e2e362b340a324f1c15a4666d75bee860d89e3cefe1
settlement dvp-1790687799143875 by app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e, 0 ho
withdrawing 00b77ba11301519e (settlement dvp-1790687799143875): disclosing 0 contract(s) the registry named
withdrawn: 122010ec311ee14fd721884a3630f21b52773b0f4a9a7c6e46e94fd858e0da3261c0 at offset 12778 with 2 event(s)
--- v2_allocate
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver = sender: authorising both sides of the leg in this allocation
holdings: 2 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 122060392d80bd84162d78a66a99bf1a27754531d1553defcc4e5c3a2a9722ea7b83 at offset 12781 with 2 event(s)
the executor settles this batch with:
settlement id: dvp-1790687804433583
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 008ea96ea80011a23fac9b9da71d829f5cfcb4e02006b7ff50c69992f4fefa835cca121220ad9135325532c99ff85d559aa8f8b80bff293f5d691769655382f75
--- v2_settle
executor: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
allocations: 1 naming it as executor
settlement dvp-1790687804433583: 1 allocation(s), 1 leg(s)
leg leg-1: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e -> app_provider_builder-localne
disclosing 2 contract(s) the registry named
settled: 1220dc87deebeb1be4fc3832672237cf6bd6685f5746db5c8066bfb69afc6069dd49 at offset 12784 with 4 event(s)
### step 5
Container pqs-scribe-1 Started
pqs ready at offset 12784
test a_refused_connection_is_not_retried_forever ... ok
test pqs_reports_how_far_it_has_ingested ... ok
test a_contract_read_from_postgres_is_the_generated_type ... ok
test an_ordered_comparison_is_a_statement_postgres_accepts ... ok
test a_payload_predicate_filters_in_the_database ... ok
test containment_and_party_columns_work_against_the_real_schema ... ok
test a_contract_is_found_by_id ... ok
test the_acs_can_be_read_as_of_an_offset ... ok
test a_connection_the_store_closes_is_replaced_on_the_next_read ... ok
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.34s
### done 2026-09-29T13:17:30Z
Every step passed as written; the five examples printed the kind the registry
answered, the disclosed-contract count and their update id and offset, and
v2_settle settled the allocation the step before created.
DevNet, 2026-09-29, at v0.3.1
The same fresh clone, run against Nodejumper’s DevNet validator (the
participant reported Ledger API 3.5.19 that day; Splice 0.8.1) with the public
SV Scan as the registry and the validator’s own party
(nodejumper-dev-1::1220a5cd…) as sender, receiver and executor.
| Suite / example | Result |
|---|---|
canton-ledger live | 36 passed |
interactive_live (external signing) | 3 passed |
canton-token registry live | 5 passed |
canton-pqs live, Scribe 3.5.4 over TLS following the participant from its latest offset | 9 passed, store ready at offset 3874307 |
submit_and_read, recover_a_submission, canton-sample | committed; the duplicate refused as DUPLICATE_COMMAND and the original outcome recovered; the typed loop on both transports |
json_packages / fetch_packages | 290 packages known, 290 written |
Read back from the participant by update id
The six example runs, read back over the JSON Ledger API
(POST /v2/updates/update-by-id) after the run; record times are the
synchronizer’s.
| Example | Update id | Offset | Record time |
|---|---|---|---|
v1_transfer | 1220ebc554e79602ca58b5cede1a60bf28a05eead6ee625c4e5590b576a1e0873b6d | 3874147 | 2026-09-29T10:09:00.343272Z |
v2_transfer | 12203fbcf8faeeb8113006e9575dd1ad9d8c7d2dc50f4b06acb2778eb76f186233d5 | 3874160 | 2026-09-29T10:09:05.583538Z |
v2_allocate | 122066fb28a402e4d80fcd1d5cad14221fb871fe33fcea38b55de6d9557219e8b6e2 | 3874169 | 2026-09-29T10:09:11.593049Z |
v2_withdraw_allocation | 1220d6cddeee588d4a5573fb8caf152397a0168f94bc482e190d3e327cabb6bba22b | 3874175 | 2026-09-29T10:09:17.353045Z |
v2_allocate | 122077f9e709bb1fa02111f62b75dfd3a4ae108de95d999dd8942dee89b9db923eff | 3874181 | 2026-09-29T10:09:22.243755Z |
v2_settle | 12209cdb5421ab0a1791651d6a637726abc5e1505caef97fc1edf94a0311aad24610 | 3874198 | 2026-09-29T10:09:28.453035Z |
V2 settlement between three parties on three participants, 2026-10-13
The settlements above have one party as sender, receiver and executor. This run has three, each on its own participant and each submitting its own step with its own participant’s token: the sender reserves its holding, the receiver consents to be paid, and the executor settles both allocations as one batch through Amulet’s settlement factory.
| LocalNet | Canton Builder Tool (Canton 3.5.7) with the App User validator added (canton builder start --with app-user): three participants on one synchronizer |
| Registry | the LocalNet’s own Scan, http://scan.localhost:4000; instrument Amulet, amount 1.0 |
| Code | main plus the receiver’s mode of v2_allocate (CANTON_TOKEN_SIDE=receiver); the SDK library is unchanged since v0.3.1 |
| Role | Party | Participant | Step |
|---|---|---|---|
| Sender | app_provider_builder-localnet-1::122050a3… | app-provider, :3901 | v2_allocate: the sender’s side, one holding reserved |
| Receiver | app_user_builder-localnet-1::12201187… | app-user, :2901 | v2_allocate with CANTON_TOKEN_SIDE=receiver and the sender’s settlement id: the receiver’s side |
| Executor | sv::1220e8c9… | sv, :4901 | v2_settle: both allocations settled as one batch |
Commands
export CANTON_TOKEN_REGISTRY_URL=http://scan.localhost:4000 CANTON_TOKEN_INSTRUMENT=Amulet CANTON_TOKEN_AMOUNT=1.0
export CANTON_TOKEN_SENDER='<app_provider party>' CANTON_TOKEN_RECEIVER='<app_user party>' CANTON_TOKEN_EXECUTOR='<sv party>'
# 1. the sender, on the app-provider participant
CANTON_TOKEN=$(canton builder token --validator app-provider) CANTON_TEST_ENDPOINT=http://localhost:3901 \
cargo run -p canton-token --example v2_allocate # prints the settlement id
# 2. the receiver, on the app-user participant
CANTON_TOKEN=$(canton builder token --validator app-user) CANTON_TEST_ENDPOINT=http://localhost:2901 \
CANTON_TOKEN_SIDE=receiver CANTON_TOKEN_SETTLEMENT_ID='<settlement id>' \
cargo run -p canton-token --example v2_allocate
# 3. the executor, on the sv participant
CANTON_TOKEN=$(canton builder token --validator sv) CANTON_TEST_ENDPOINT=http://localhost:4901 \
CANTON_TOKEN_SETTLEMENT='<settlement id>' cargo run -p canton-token --example v2_settle
The balances before and after are each party’s Amulet holdings, read from its
own participant’s JSON Ledger API through the Holding interface.
Output
### V2 DvP, three parties on three participants, 1e933c8 2026-10-13T11:20:38Z
sender app_provider_builder-localnet-1::… (app-provider participant, :3901)
receiver app_user_builder-localnet-1::… (app-user participant, :2901)
executor sv::… (sv participant, :4901)
--- before: sender 1 holding(s), 190320.3200000000 Amulet; receiver 0 holding(s), 0 Amulet
--- 1. sender allocates its side (app-provider token)
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver: app_user_builder-localnet-1::12201187a79fd5e9d82a80c85a0460893193edf9adc696e37ccde66a2343d328f246
executor: sv::1220e8c961fae7b4034ce31a84388aeb59cc00c8089a9af03aa1cafb0649d328d861
side: sender
holdings: 1 unlocked holding(s) of Amulet read from the ledger
disclosing: 2 contract(s) the registry named
allocated: 1220973efa56a4f1abaa2e7fa19a9749da150ab06eb54e6063a80039cbf7e8c398f9 at offset 13781 with 6 event(s)
the executor settles this batch with:
settlement id: dvp-1791890468907761
executor: sv::1220e8c961fae7b4034ce31a84388aeb59cc00c8089a9af03aa1cafb0649d328d861
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00890f7477f223e750268c59f9f8c340c8a34c34f0da952ab2677c843661082cf8ca121220e2b9a78989677f876939365cf13d71e356b97241b7b4ef64db9a4122c7c2a35d
created: 00ad91eece6966cfdcffa618aa0cf5a50d03d200ba9e8b320789989af28c16aca3ca121220b4670ec236fead19ed728943c4add0008f01b628b7f7771deaf19b3fda52fc49
created: 007360ee16c857b9062e5490a0a7b6e86098395a89110f2b997f319365d5497fe2ca1212209f68e83c33c641059f59466a9ae706cfafd9475ef7c0f21270f7106590c19069
--- 2. receiver allocates its side of dvp-1791890468907761 (app-user token)
registry admin: DSO::1220da56976bc0f405bfffaf268f075cfb2d0d0224f2115b214a38cf03db1b2cedad
sender: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e
receiver: app_user_builder-localnet-1::12201187a79fd5e9d82a80c85a0460893193edf9adc696e37ccde66a2343d328f246
executor: sv::1220e8c961fae7b4034ce31a84388aeb59cc00c8089a9af03aa1cafb0649d328d861
side: receiver
disclosing: 2 contract(s) the registry named
allocated: 1220e7606e818594c8af1c4cb7ea7f1fc1bd405adc6d4ca743ff7427e469b7c43fc0 at offset 181 with 2 event(s)
the executor settles this batch with:
settlement id: dvp-1791890468907761
executor: sv::1220e8c961fae7b4034ce31a84388aeb59cc00c8089a9af03aa1cafb0649d328d861
v2::settle_batch(®istry, settlement, transfer_legs, allocations, vec![executor])
created: 00296653c978314158feffc8e08da6f023947fed7b2e43657fae6c02d4ef1556f6ca121220e293f9c24e71953a778797f12bbe3f55e56cf6d5c28037160d0074fd9f5b6858
--- 3. executor settles dvp-1791890468907761 (sv token)
executor: sv::1220e8c961fae7b4034ce31a84388aeb59cc00c8089a9af03aa1cafb0649d328d861
allocations: 2 naming it as executor
settlement dvp-1791890468907761: 2 allocation(s), 1 leg(s)
leg leg-1: app_provider_builder-localnet-1::122050a3b417325869df2a2248607ef4d408abdd45da8d7c4e774f96c090e32cd11e -> app_user_builder-localnet-1::12201187a79fd5e9d82a80c85a0460893193edf9adc696e37ccde66a2343d328f246 : 1.0000000000 Amulet
disclosing 3 contract(s) the registry named
settled: 122062792e2766b8b39d77d65f16e2027586cb61a181c1107113f8efd144f5f54dfd at offset 23299 with 9 event(s)
--- after: sender 1 holding(s), 190319.3200000000 Amulet; receiver 1 holding(s), 1.0000000000 Amulet
### done 2026-10-13T11:21:14Z
Read back from each participant by update id
The settlement is one transaction on the synchronizer, so the three participants report the same record time at their own offsets.
| Update | Read as | Participant | Offset | Record time |
|---|---|---|---|---|
sender’s allocation 1220973efa56a4f1abaa… | sender | app-provider | 13781 | 2026-10-13T11:21:09.453125Z |
receiver’s allocation 1220e7606e818594c8af… | receiver | app-user | 181 | 2026-10-13T11:21:11.201934Z |
settlement 122062792e2766b8b39d… | sender | app-provider | 13784 | 2026-10-13T11:21:13.592559Z |
settlement 122062792e2766b8b39d… | receiver | app-user | 184 | 2026-10-13T11:21:13.592559Z |
settlement 122062792e2766b8b39d… | executor | sv | 23299 | 2026-10-13T11:21:13.592559Z |
The sender ends 1 Amulet lower and the receiver, which held none, holds 1 Amulet: the leg moved between two parties on two participants, settled by a third.