Decoupling Application DAR Dependencies from Splice Amulet Upgrades
Hi everyone,
We have built a non-custodial Gift escrow application on Canton Network.
Our Gift DAR currently has data dependencies on both the stable Token Standard
interfaces and the concrete Splice Amulet package:
- splice-api-token-metadata-v1
- splice-api-token-holding-v1
- splice-api-token-transfer-instruction-v1
- splice-amulet
The Gift contract currently uses concrete Splice templates and choices such as:
- AmuletRules_Transfer
- LockedAmulet
- LockedAmulet_UnlockV2
- Amulet
At gift creation, the creator’s Amulet is converted into a LockedAmulet. The
creator remains the owner, while our operator is only a lock holder. When an
unknown user claims the gift, the Gift contract unlocks the LockedAmulet and
delivers it to the claimer through TransferFactory_Transfer.
This gives us the properties we need:
- The creator cannot double-spend the gifted funds.
- Our operator never owns or can redirect the funds.
- The creator does not need to be online when the gift is claimed.
- An initially unknown claimer can claim through a disclosed Gift contract.
- Unclaimed funds can only return to the creator after expiry.
The maintenance problem is that our DAR is compiled against a concrete
splice-amulet package. When Splice upgrades the Amulet package, the active
AmuletRules and newly created Amulet/LockedAmulet contracts use the new package
version. We therefore need to update the data dependency, rebuild and redeploy
our Gift DAR and update the corresponding package IDs in our backend.
We would like to reduce this coupling and keep the core Gift DAR stable across
Splice upgrades.
Questions:
-
Is there a recommended way for an application DAR to depend only on the
stable CIP-0056 Token Standard interfaces while still creating, locking and
later unlocking a holding? -
HoldingV1/HoldingV2 exposes a generic holding view, but is there a stable
interface for creating a time-locked holding and releasing that lock without
importing the concrete Splice LockedAmulet and AmuletRules templates? -
Can a ContractId of a concrete LockedAmulet safely be stored and exercised
through a stable interface, including its unlock operation? -
Would Daml package upgrades solve this dependency problem, or would the Gift
package still need to be rebuilt because its choices refer to concrete
Amulet types in their signatures and implementation? -
Is the recommended pattern to split the application into:
- a stable Gift core package, and
- a small version-specific Splice/Amulet adapter package
that is replaced after each Splice upgrade?
-
If an adapter package is recommended, how should authority be delegated so
that the adapter can unlock and transfer the funds but cannot redirect or
withdraw them? -
Can old application contracts continue interacting safely with the upgraded
Amulet ecosystem, or should applications expect to migrate all active Gift
contracts whenever the network changes the active Amulet package?
Our main objective is not merely dynamic package-ID discovery in the backend.
We want to remove, or at least isolate, the compile-time dependency on concrete
Splice Amulet implementations while preserving the non-custodial guarantees
above.
Is there an official or recommended architecture for this use case?
Thank you.
Great questions.
I really appreciate seeing builders openly discussing architecture and long-term maintainability. Looking forward to the recommendations from the Canton team and seeing Askardex continue to improve ![]()