Documentation Index
Fetch the complete documentation index at: https://cantonfoundation-mintlify-validate-diagnosis.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Proof of Transfer
Overview
Privacy-enabled assets on the Canton Network, such as DA registry assets, require a specialized mechanism for users to verify transaction outcomes while preserving the privacy of the involved parties. Users need a way to independently and indisputably verify that an asset transfer was successful, obtaining a reliable, network-verified confirmation that is independent of any single platform’s internal reporting. To enable this transfer proofing capability, wallets must make the Transfer Object payload and UpdateID extractable, allowing end-users to easily locate and copy this data directly from their transaction history to use in proofing services or network explorers. This guide provides the technical specifications for locating and extracting the Transfer Object from the ledger via the JSON API.Exposing the Transfer Object and UpdateID
Technical Guidelines: What Constitutes the Transfer Object?
The UpdateID is the unique identifier for a transaction on the ledger. With it, you can fetch the Created, Exercised, and Archived events for that specific transaction. NOTE: The wallets needs to ensure that they display the most recent updated for a given transfer. For example, in the case of a 2 step transfer, Wallet Providers will need to explicitly refresh the updateID, after the transaction has been accepted, so that they display the transfer, not just the offer. The underlying schema defining the Transfer Object can be referenced in the DAML model here:Splice/Api/Token/TransferInstructionV1.daml
The Transfer Object can also be serialized into JSON format, as shown in the following example:
GET /v2/updates/update-by-id
Locating the Transfer Object (By Transaction State)
Depending on the lifecycle stage of the transaction, the Transfer Object is located in different event arguments. You will need to parse the events returned from the endpoint above based on these three scenarios: Scenario A: The Transfer Offer is Created If the update represents the creation of a transfer offer, look for a Created event.- Template:
Utility.Registry.App.V0.Model.Transfer:TransferOffer - Location: Extract the Transfer Object directly from the
createArgumentof this event.
-
Template:
Utility.Registry.V0.Rule.Transfer:TransferRule -
Triggering Choices: The event must be triggered by one of the following choices:
TransferRule_DirectTransferTransferRule_TwoStepTransferTransferRule_Transfer(This choice will be deprecated. It is only required for backwards compatibility)
-
Location: Extract the Transfer Object from the
choiceArgumentof this event.
- Identify the Event: Look for an Exercised event matching the following:
- Interface ID:
Splice.Api.Token.TransferInstructionV1:TransferInstruction - Triggering Choices:
TransferInstruction_RejectORTransferInstruction_Withdraw
- Interface ID:
- Fetch the Contract ID: Extract the Contract ID of the transfer offer from this exercised event.
- Fetch the Original Offer: Query the JSON API using the extracted Contract ID:
GET /v2/events/events-by-contract-id - Location: Extract the Transfer Object from the
createArgumentof the original transfer offer (transfer instruction) returned by this secondary query.
Data Persistence and Pruning
Ledger data is subject to pruning. The JSON API queries described in previous section will only succeed if the transaction events have not yet been pruned from the participant node. Wallet Developer Action Required: To ensure end-users can always access their Transfer Objects for the proofing service, wallets MUST persist the Transfer Object and UpdateID data in their own backend databases at the time the transaction occurs. Relying strictly on real-time ledger queries for historical transactions will result in errors once the transactions are pruned. PQS can be considered as an option for storing ledger data.Locating the Transfer Object (as an end-user)
Labelling There are two key items to be displayed within the transaction details:- Updated ID
- Transfer object
- Click to open a modal/side-panel component or an external browser window. Since the content is hidden to start, when a user clicks to open this component, the json object should by default be displayed fully. This component shows the label of “Transfer object”, contains the full json object for reviewing, and accessible copy button.
- If an external window is used, its domain must match the application domain from which the window was triggered.
- The icon or button for a user to click to review the json object must be accessible, along side the copy icon/button. Users can copy the object without opening the review component.
- Click to open the accordion containing the content. The accordion is closed by default, and a copy button is accessible without opening the accordion.