Transaction History Ingestion Details

Offset Checkpoints

When consuming transactions through the update service at /v2/updates you will not just receive transactions but you will also receive offset checkpoints. Each offset checkpoint contains an offset and the most recent observed record time for each synchronizer. Your Tx History Ingestion should use that to update the last processed offset and record time (in addition to updating those after each transaction) so that it will resume processing transactions from that point on after a crash or restart.

Offset checkpoints are in particular required around Major Splice Upgrades where there is no Daml transaction for an extended period of time, but you want to ensure that your Tx History Ingestion advances beyond a particular record time.

Transaction Parsing

As part of the Integration Workflows, Tx History Ingestion is expected to extract a number of fields for both deposits and withdrawals. Below we provide details on the transaction structure of the Integration Workflows and how to parse it.

Note

The following code is available to help you implement your own parsing logic:

1-Step Transfers

To understand the structure of a 1-step transfer, let’s look at an example deposit

as seen through the JSON Ledger API.

In this case, we query a single transaction. The format is identical to the transaction you will get when streaming transactions through /v2/updates/flats and you can also use the same filter. Note that you need to adjust the auth-token, update-id and treasury-party placeholders to match your setup.

curl -sSL --fail-with-body http://json-api-url/v2/updates/update-by-id \
    -H 'Authorization: Bearer <authtoken>' \
      -d '{
            "updateId": "<update-id>",
            "updateFormat": {
              "includeTransactions": {
                "transactionShape": "TRANSACTION_SHAPE_LEDGER_EFFECTS",
                "eventFormat": {
                  "filtersByParty": {
                    "<treasury-party>": {
                      "cumulative": [
                        {"identifierFilter": {"WildcardFilter": {"value": {"includeCreatedEventBlob": false}}}},
                        {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}},
                        {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-holding-v1:Splice.Api.Token.HoldingV1:Holding", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}},
                        {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferInstruction", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}}
                      ]
                    }
                  },
                  "verbose": true
                }
              }
            }
          }'
{
    "update": {
        "Transaction": {
            "value": {
                "updateId": "122008a4699e61ce682917c9515ecb3b4426adf276441e41edede8b3862efa2de80e",
                "commandId": "582f81e4-86e4-48fa-ad95-607e9ebe8c9b",
                "workflowId": "",
                "effectiveAt": "1970-01-01T00:01:00Z",
                "events": [
                    {
                        "ExercisedEvent": {
                            "offset": 107,
                            "nodeId": 4,
                            "contractId": "0003113864953b90e689737a131569e8758df3cf82e3db12c89f010ac330276f3cca1112204bc3e9f7d695217e06aec436ac87a441c8e1a0f0d3ae2668c38e408fa2d5ebda",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.AmuletRules:TransferPreapproval",
                            "interfaceId": null,
                            "choice": "TransferPreapproval_Send",
                            "choiceArgument": {
                                "context": {
                                    "amuletRules": "002402fc37d1f6fcb5c9247342c66659f95eb03efebba3da8c244ae7c10925aae2ca1112201ac4dd28e75b1ba2be4df65e674b0c66fa2ec934abc15824584d8566af4916e9",
                                    "context": {
                                        "openMiningRound": "009d18bf51238bb679b45ac760d418d31d95fead0538971a26eff6d2b2d582005dca1112204d969f7a6e0d271b3a85b27297879812e8c0fdaaaf8d72d64441a06556bb5955",
                                        "issuingMiningRounds": [],
                                        "validatorRights": [],
                                        "featuredAppRight": null
                                    }
                                },
                                "inputs": [
                                    {
                                        "tag": "InputAmulet",
                                        "value": "009b939ae451ef1a0cb81d1606391406690e055b5be301fd2f51efb6be5675577eca1112200f58604ac538224f73bdc57117d73830ed1e3167f956d66f9e3ecdacbf2359a7"
                                    }
                                ],
                                "amount": "200.0000000000",
                                "sender": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                "description": "token-standard-transfer-description"
                            },
                            "actingParties": [
                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "consuming": false,
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "lastDescendantNodeId": 12,
                            "exerciseResult": {
                                "result": {
                                    "round": {
                                        "number": "1"
                                    },
                                    "summary": {
                                        "inputAppRewardAmount": "0.0000000000",
                                        "inputValidatorRewardAmount": "0.0000000000",
                                        "inputSvRewardAmount": "0.0000000000",
                                        "inputAmuletAmount": "199877.3600000000",
                                        "balanceChanges": [
                                            [
                                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                                {
                                                    "changeToInitialAmountAsOfRoundZero": "-214.0000000000",
                                                    "changeToHoldingFeesRate": "0.0000000000"
                                                }
                                            ],
                                            [
                                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                                {
                                                    "changeToInitialAmountAsOfRoundZero": "200.0038051800",
                                                    "changeToHoldingFeesRate": "0.0038051800"
                                                }
                                            ]
                                        ],
                                        "holdingFees": "0.0000000000",
                                        "outputFees": ["8.0000000000"],
                                        "senderChangeFee": "6.0000000000",
                                        "senderChangeAmount": "199663.3600000000",
                                        "amuletPrice": "0.0050000000",
                                        "inputValidatorFaucetAmount": "0.0000000000",
                                        "inputUnclaimedActivityRecordAmount": "0.0000000000"
                                    },
                                    "createdAmulets": [
                                        {
                                            "tag": "TransferResultAmulet",
                                            "value": "008f783cd288ce926f8bc973df7ddb719e0b8c941dd84cd9a6ca0240fb7ecff390ca111220f5d7073ad68f0746851954e570f348d099a323b796f71807caf71871fce6d956"
                                        }
                                    ],
                                    "senderChangeAmulet": "00431eabcbb8f4293ccc0e17764bca260ff64aede386245c033b2d0ebddc2cbb21ca111220e755e3b05c909e84ffbc47fa4be1e1b786af37e76479efd348a0ae2722149904",
                                    "meta": null
                                },
                                "meta": {
                                    "values": {
                                        "splice.lfdecentralizedtrust.org/burned": "14.0",
                                        "splice.lfdecentralizedtrust.org/reason": "deposit-account-id",
                                        "splice.lfdecentralizedtrust.org/sender": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                        "splice.lfdecentralizedtrust.org/tx-kind": "transfer"
                                    }
                                }
                            },
                            "packageName": "splice-amulet",
                            "implementedInterfaces": []
                        }
                    },
                    {
                        "ExercisedEvent": {
                            "offset": 107,
                            "nodeId": 5,
                            "contractId": "002402fc37d1f6fcb5c9247342c66659f95eb03efebba3da8c244ae7c10925aae2ca1112201ac4dd28e75b1ba2be4df65e674b0c66fa2ec934abc15824584d8566af4916e9",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.AmuletRules:AmuletRules",
                            "interfaceId": null,
                            "choice": "AmuletRules_Transfer",
                            "choiceArgument": {
                                "transfer": {
                                    "sender": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                    "provider": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                    "inputs": [
                                        {
                                            "tag": "InputAmulet",
                                            "value": "009b939ae451ef1a0cb81d1606391406690e055b5be301fd2f51efb6be5675577eca1112200f58604ac538224f73bdc57117d73830ed1e3167f956d66f9e3ecdacbf2359a7"
                                        }
                                    ],
                                    "outputs": [
                                        {
                                            "receiver": "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                            "receiverFeeRatio": "0.0000000000",
                                            "amount": "200.0000000000",
                                            "lock": null
                                        }
                                    ],
                                    "beneficiaries": null
                                },
                                "context": {
                                    "openMiningRound": "009d18bf51238bb679b45ac760d418d31d95fead0538971a26eff6d2b2d582005dca1112204d969f7a6e0d271b3a85b27297879812e8c0fdaaaf8d72d64441a06556bb5955",
                                    "issuingMiningRounds": [],
                                    "validatorRights": [],
                                    "featuredAppRight": null
                                },
                                "expectedDso": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962"
                            },
                            "actingParties": [
                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "consuming": false,
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "lastDescendantNodeId": 12,
                            "exerciseResult": {
                                "round": {
                                    "number": "1"
                                },
                                "summary": {
                                    "inputAppRewardAmount": "0.0000000000",
                                    "inputValidatorRewardAmount": "0.0000000000",
                                    "inputSvRewardAmount": "0.0000000000",
                                    "inputAmuletAmount": "199877.3600000000",
                                    "balanceChanges": [
                                        [
                                            "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                            {
                                                "changeToInitialAmountAsOfRoundZero": "-214.0000000000",
                                                "changeToHoldingFeesRate": "0.0000000000"
                                            }
                                        ],
                                        [
                                            "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                            {
                                                "changeToInitialAmountAsOfRoundZero": "200.0038051800",
                                                "changeToHoldingFeesRate": "0.0038051800"
                                            }
                                        ]
                                    ],
                                    "holdingFees": "0.0000000000",
                                    "outputFees": ["8.0000000000"],
                                    "senderChangeFee": "6.0000000000",
                                    "senderChangeAmount": "199663.3600000000",
                                    "amuletPrice": "0.0050000000",
                                    "inputValidatorFaucetAmount": "0.0000000000",
                                    "inputUnclaimedActivityRecordAmount": "0.0000000000"
                                },
                                "createdAmulets": [
                                    {
                                        "tag": "TransferResultAmulet",
                                        "value": "008f783cd288ce926f8bc973df7ddb719e0b8c941dd84cd9a6ca0240fb7ecff390ca111220f5d7073ad68f0746851954e570f348d099a323b796f71807caf71871fce6d956"
                                    }
                                ],
                                "senderChangeAmulet": "00431eabcbb8f4293ccc0e17764bca260ff64aede386245c033b2d0ebddc2cbb21ca111220e755e3b05c909e84ffbc47fa4be1e1b786af37e76479efd348a0ae2722149904",
                                "meta": {
                                    "values": {
                                        "splice.lfdecentralizedtrust.org/burned": "14.0",
                                        "splice.lfdecentralizedtrust.org/sender": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                        "splice.lfdecentralizedtrust.org/tx-kind": "transfer"
                                    }
                                }
                            },
                            "packageName": "splice-amulet",
                            "implementedInterfaces": []
                        }
                    },
                    {
                        "ExercisedEvent": {
                            "offset": 107,
                            "nodeId": 8,
                            "contractId": "009b939ae451ef1a0cb81d1606391406690e055b5be301fd2f51efb6be5675577eca1112200f58604ac538224f73bdc57117d73830ed1e3167f956d66f9e3ecdacbf2359a7",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "interfaceId": null,
                            "choice": "Archive",
                            "choiceArgument": {},
                            "actingParties": [
                                "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "consuming": true,
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "lastDescendantNodeId": 8,
                            "exerciseResult": {},
                            "packageName": "splice-amulet",
                            "implementedInterfaces": [
                                "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding"
                            ]
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 107,
                            "nodeId": 9,
                            "contractId": "004d3b89582b1d286a067ea783675350f61fe1d700319deeaa5fc35a81f9357172ca111220c529ebbcad9fcce4d6a6fbc3eda16ce0155f93896df5ba212d1e959b289814b3",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:ValidatorRewardCoupon",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "user": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                "amount": "8.0000000000",
                                "round": {
                                    "number": "1"
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [],
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "signatories": [
                                "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962"
                            ],
                            "observers": [
                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 107,
                            "nodeId": 10,
                            "contractId": "002a7815f107134bfd776bbc50bb7ead071a050cd651e3d7d15f6ac1f970403558ca111220554d2712f9bf057953688d5fc2aaab8d890e37fe9023f4522a4a53a40d4cf538",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:AppRewardCoupon",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "provider": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                "featured": false,
                                "amount": "8.0000000000",
                                "round": {
                                    "number": "1"
                                },
                                "beneficiary": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [],
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "signatories": [
                                "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962"
                            ],
                            "observers": [
                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 107,
                            "nodeId": 11,
                            "contractId": "008f783cd288ce926f8bc973df7ddb719e0b8c941dd84cd9a6ca0240fb7ecff390ca111220f5d7073ad68f0746851954e570f348d099a323b796f71807caf71871fce6d956",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "owner": "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                "amount": {
                                    "initialAmount": "200.0000000000",
                                    "createdAt": {
                                        "number": "1"
                                    },
                                    "ratePerRound": {
                                        "rate": "0.0038051800"
                                    }
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [
                                {
                                    "interfaceId": "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding",
                                    "viewStatus": {
                                        "code": 0,
                                        "message": "",
                                        "details": []
                                    },
                                    "viewValue": {
                                        "owner": "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                        "instrumentId": {
                                            "admin": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                            "id": "Amulet"
                                        },
                                        "amount": "200.0000000000",
                                        "lock": null,
                                        "meta": {
                                            "values": {
                                                "amulet.splice.lfdecentralizedtrust.org/created-in-round": "1",
                                                "amulet.splice.lfdecentralizedtrust.org/rate-per-round": "0.00380518"
                                            }
                                        }
                                    }
                                }
                            ],
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "signatories": [
                                "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "observers": [],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 107,
                            "nodeId": 12,
                            "contractId": "00431eabcbb8f4293ccc0e17764bca260ff64aede386245c033b2d0ebddc2cbb21ca111220e755e3b05c909e84ffbc47fa4be1e1b786af37e76479efd348a0ae2722149904",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "owner": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                "amount": {
                                    "initialAmount": "199663.3600000000",
                                    "createdAt": {
                                        "number": "1"
                                    },
                                    "ratePerRound": {
                                        "rate": "0.0038051800"
                                    }
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [
                                {
                                    "interfaceId": "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding",
                                    "viewStatus": {
                                        "code": 0,
                                        "message": "",
                                        "details": []
                                    },
                                    "viewValue": {
                                        "owner": "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd",
                                        "instrumentId": {
                                            "admin": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                            "id": "Amulet"
                                        },
                                        "amount": "199663.3600000000",
                                        "lock": null,
                                        "meta": {
                                            "values": {
                                                "amulet.splice.lfdecentralizedtrust.org/created-in-round": "1",
                                                "amulet.splice.lfdecentralizedtrust.org/rate-per-round": "0.00380518"
                                            }
                                        }
                                    }
                                }
                            ],
                            "witnessParties": [
                                "treasury-party::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "signatories": [
                                "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                                "sender::1220278a4a0eb2c244b425dff62853ef1cd04ca1095bffcea465c0de766faf9ab8cd"
                            ],
                            "observers": [],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    }
                ],
                "offset": 107,
                "synchronizerId": "global-domain::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962",
                "traceContext": {
                    "traceparent": "00-a02f704bef12ca819b369d2c2c037c55-4bc4bdde1e4377b5-01",
                    "tracestate": null
                },
                "recordTime": "1970-01-01T00:01:00.000114Z"
            }
        }
    }
}

You can parse such transactions using the token standard history parser provided in the wallet SDK to extract the deposit amount, account and holding contract ids. Note that one-step deposits are more complex to parse than two-step transfers as the token standard does not provide an interface choice visible to the receiver. If you prefer implementing your own implementation, you can parse this as follows:

  1. Go over the list of events ordered by nodeId that you see in the transaction.

  2. For each exercised event, check the exercise result. If it has a field called `meta with a "splice.lfdecentralizedtrust.org/tx-kind": "transfer" field you found a transfer. In the example here, this is the event with nodeId 4 which exercises the TransferPreapproval_Send choice. Note that this choice is specific to Canton Coin so rely on the existence of the meta field which is standardized instead of the specific choice name.

  3. Extract the "splice.lfdecentralizedtrust.org/reason" to get the deposit account. In this example it is deposit-account-id.

  4. Go over all events whose nodeId is larger than the nodeId of the transfer (4 in the example here) and smaller than the lastDescendantNodeId of the transfer (12 in the example here).

  5. Find all CreatedEvents in that range that create a Holding with "owner": "<treasury-party>" and sum up the amounts for each instrumentId. In this example, we have two events that create holdings, nodeId 11 and 12. However, only 12 has "owner": "<treasury-party>". Therefore, we extract that the transfer created 200.0000000000 for the token with instrument id {"admin": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962", "id": "Amulet"}.

  6. Find all ExercisedEvents with implementedInterfaces containing the Holding interface and consuming: true. In the example here, this is the event with nodeId:: 8. For each of them get the contractId and lookup the contract payload through the event query service as shown below. If you get a 404, it’s a holding for a different party so you can ignore it. If you get back an event, check if "owner": "<treasury-party>". If so, sum up all events for which this is the case. In the example here, we get a 404 as it is a holding of the sender not treasury-party.

    curl -sSL --fail-with-body http://json-api-url/v2/events/events-by-contract-id \
      -H 'Authorization: Bearer 721580fa5edea5c12b887af1dba4ed2381c507d1a94c96aa63685198c958bf3ddd951d3cb004ead720c61734d4035c442afc102896cdb75e1c0883f61828eaed' \
        -d '{
          "contractId": "009b939ae451ef1a0cb81d1606391406690e055b5be301fd2f51efb6be5675577eca1112200f58604ac538224f73bdc57117d73830ed1e3167f956d66f9e3ecdacbf2359a7",
          "eventFormat": {
            "filtersByParty": {
              "<treasury-party>": {
                "cumulative": [
                  {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-holding-v1:Splice.Api.Token.HoldingV1:Holding", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}}
                ]
              }
            },
            "verbose": true
          }
        }'
    
  7. Subtract the sum of archived holdings for the treasury-party from the sum of created holdings. This gives you the deposit amount for each instrument id. You now extracted the deposit amount from the created and exercised events, the UTXOs from the created events and the deposit acount from the splice.lfdecentralizedtrust.org/reason field.

  8. Continue with the events starting at node id lastDescendantNodeId + 1. Note that in this example this skips over the event with nodeId: 5 which exercises AmuletRules_Transfer. This is important as you already accounted for this event through the parent event at node id 4. Note that one transaction can contain multiple deposits including mixing 1 and 2-step deposits in the same transaction.

Differences between 1-Step Deposits and Withdrawals

The example we discussed above, shows a deposit. A withdrawal is essentially the same transaction but sender and receiver are swapped. For a withdrawal, the sender, i.e. the treasury party for an exchange, will also see the TransferFactory_Transfer choice as a parent and you can extract the amount and reason from that instead of looking for the meta field in exercise results.

Note however, that for Canton Coin the amount in the TransferFactory_Transfer argument will be higher than the difference of holdings archived and created for the treasury party due to Canton Coin usage fees. Once the CIP for CC fee removal is implemented, this distinction goes away. Currently Canton Coin is the only token on Canton Network charging such fees.

Multi-Step Transfers

To understand the transaction structure of a multi-step transfer, let’s look at an example transaction of a Multi-Step Deposit as seen through the JSON Ledger API.

In this case, we query a single transaction. The format is identical to the transaction you will get when streaming transactions through /v2/updates/flats and you can also use the same filter. Note that you need to adjust the auth-token, update-id and treasury-party placeholders to match your setup.

curl -sSL --fail-with-body http://json-api-url/v2/updates/update-by-id \
    -H 'Authorization: Bearer <authtoken>' \
      -d '{
            "updateId": "<update-id>",
            "updateFormat": {
              "includeTransactions": {
                "transactionShape": "TRANSACTION_SHAPE_LEDGER_EFFECTS",
                "eventFormat": {
                  "filtersByParty": {
                    "<treasury-party>": {
                      "cumulative": [
                        {"identifierFilter": {"WildcardFilter": {"value": {"includeCreatedEventBlob": false}}}},
                        {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}},
                        {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-holding-v1:Splice.Api.Token.HoldingV1:Holding", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}},
                        {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferInstruction", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}}
                      ]
                    }
                  },
                  "verbose": true
                }
              }
            }
          }'
{
    "update": {
        "Transaction": {
            "value": {
                "updateId": "12208359521a283dbd0749c2a38c858ad71612fd5177aa95fb736e77fd181b8060c7",
                "commandId": "",
                "workflowId": "",
                "effectiveAt": "1970-01-01T00:01:00Z",
                "events": [
                    {
                        "CreatedEvent": {
                            "offset": 96,
                            "nodeId": 0,
                            "contractId": "00fc774936c91f423c117744102a5996e4dc117f2b6496ef337967a7d2c5d02e4aca1112203c35266c980ae19508cc690cb501f8c767c02bfdbe838f1f89105de6fe59439f",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.AmuletTransferInstruction:AmuletTransferInstruction",
                            "contractKey": null,
                            "createArgument": {
                                "lockedAmulet": "004ef3ae401af384aa37391f3a975647b1ca3d9ca3dc97f7b1e19c47d013ed4956ca11122015cac2e81f6d2e2735ed64c16326230234cc374c85ed42657b7801bf62233ddc",
                                "transfer": {
                                    "sender": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                    "receiver": "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87",
                                    "amount": "1000.0000000000",
                                    "instrumentId": {
                                        "admin": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                        "id": "Amulet"
                                    },
                                    "requestedAt": "1970-01-01T00:01:00Z",
                                    "executeBefore": "1970-01-01T00:02:00Z",
                                    "inputHoldingCids": [
                                        "004ef3ae401af384aa37391f3a975647b1ca3d9ca3dc97f7b1e19c47d013ed4956ca11122015cac2e81f6d2e2735ed64c16326230234cc374c85ed42657b7801bf62233ddc"
                                    ],
                                    "meta": {
                                        "values": {
                                            "splice.lfdecentralizedtrust.org/reason": "deposit-account-id"
                                        }
                                    }
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [
                                {
                                    "interfaceId": "55ba4deb0ad4662c4168b39859738a0e91388d252286480c7331b3f71a517281:Splice.Api.Token.TransferInstructionV1:TransferInstruction",
                                    "viewStatus": {
                                        "code": 0,
                                        "message": "",
                                        "details": []
                                    },
                                    "viewValue": {
                                        "originalInstructionCid": null,
                                        "transfer": {
                                            "sender": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                            "receiver": "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87",
                                            "amount": "1000.0000000000",
                                            "instrumentId": {
                                                "admin": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                                "id": "Amulet"
                                            },
                                            "requestedAt": "1970-01-01T00:01:00Z",
                                            "executeBefore": "1970-01-01T00:02:00Z",
                                            "inputHoldingCids": [
                                                "004ef3ae401af384aa37391f3a975647b1ca3d9ca3dc97f7b1e19c47d013ed4956ca11122015cac2e81f6d2e2735ed64c16326230234cc374c85ed42657b7801bf62233ddc"
                                            ],
                                            "meta": {
                                                "values": {
                                                    "splice.lfdecentralizedtrust.org/reason": "deposit-account-id"
                                                }
                                            }
                                        },
                                        "status": {
                                            "tag": "TransferPendingReceiverAcceptance",
                                            "value": {}
                                        },
                                        "meta": {
                                            "values": {}
                                        }
                                    }
                                }
                            ],
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "signatories": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "observers": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    }
                ],
                "offset": 96,
                "synchronizerId": "global-domain::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                "traceContext": {
                    "traceparent": "00-5272bc75d4e43cc836ad878ee28fd812-63cd1b00c1d96ad3-01",
                    "tracestate": null
                },
                "recordTime": "1970-01-01T00:01:00.000145Z"
            }
        }
    }
}

You can parse such transactions using the token standard history parser provided in the wallet SDK to extract the deposit amount, account and holding contract ids. If you prefer implementing your own implementation, you can parse this as follows:

  1. Go over the list of events ordered by nodeId that you see in the transaction.

  2. Look for all CreatedEvents of the TransferInstruction interface with "receiver": "<treasury-party>". Each of these represents a deposit offer that can be accepted or rejected. In the example this is only one event with node id 0. Extract the instrument, the amount and the splice.lfdecentralizedtrust.org/reason field from the interfaceView and the contract id of the TransferInstruction. Note that one transaction can contain multiple deposits including mixing 1 and 2-step deposits in the same transaction.

After accepting the deposit offer through your automation, Tx History Ingestion can then observe and process acceptance. An example of such a transaction can be seen below.

{
    "update": {
        "Transaction": {
            "value": {
                "updateId": "122027b71f7eae8f7c42e39fba745da860fed5254c32d4afbd1699deff19e5fc4206",
                "commandId": "d5e461d9-405d-4042-bea2-6eca4b82548c",
                "workflowId": "",
                "effectiveAt": "1970-01-01T00:01:00Z",
                "events": [
                    {
                        "ExercisedEvent": {
                            "offset": 106,
                            "nodeId": 0,
                            "contractId": "00fc774936c91f423c117744102a5996e4dc117f2b6496ef337967a7d2c5d02e4aca1112203c35266c980ae19508cc690cb501f8c767c02bfdbe838f1f89105de6fe59439f",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.AmuletTransferInstruction:AmuletTransferInstruction",
                            "interfaceId": "55ba4deb0ad4662c4168b39859738a0e91388d252286480c7331b3f71a517281:Splice.Api.Token.TransferInstructionV1:TransferInstruction",
                            "choice": "TransferInstruction_Accept",
                            "choiceArgument": {
                                "extraArgs": {
                                    "context": {
                                        "values": {
                                            "amulet-rules": {
                                                "tag": "AV_ContractId",
                                                "value": "001b1c0752079634f968fb59cdf0ec5b4aa9a085d939f1d443ca1b2a6d050e3927ca1112204b53a7228d1305d18dc568701cfdab4f60fc193d6c2e8e09c69582b2790e3550"
                                            },
                                            "expire-lock": {
                                                "tag": "AV_Bool",
                                                "value": true
                                            },
                                            "open-round": {
                                                "tag": "AV_ContractId",
                                                "value": "00c298815a41f51f7b6a164f7a2618e03b3caa2022a1919da05b2a4aa6400f40b4ca111220f7b646f00988b0a32aa21a5ab16f5962978b108c4ff37fcc944cdb7c40e56669"
                                            }
                                        }
                                    },
                                    "meta": {
                                        "values": {}
                                    }
                                }
                            },
                            "actingParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "consuming": true,
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "lastDescendantNodeId": 12,
                            "exerciseResult": {
                                "output": {
                                    "tag": "TransferInstructionResult_Completed",
                                    "value": {
                                        "receiverHoldingCids": [
                                            "0026638a9b9db54fab1cc3f260b4db189a8e65e8bdaf646a66fdff3976a48e88a6ca1112209d4295be34eb089d5b94ed0c681723a2591681f09de55a95de8040c822726306"
                                        ]
                                    }
                                },
                                "senderChangeCids": [
                                    "009d1ed65f5ab6fb57fddf2de3671bc734807ec4aaba3f37b539388787e1adb250ca111220bed445fb61640859f9ed394ae51d029e2b5cd113c6df9bdd8633333ba1dfc8e8"
                                ],
                                "meta": {
                                    "values": {
                                        "splice.lfdecentralizedtrust.org/burned": "22.0"
                                    }
                                }
                            },
                            "packageName": "splice-amulet",
                            "implementedInterfaces": [
                                "55ba4deb0ad4662c4168b39859738a0e91388d252286480c7331b3f71a517281:Splice.Api.Token.TransferInstructionV1:TransferInstruction"
                            ]
                        }
                    },
                    {
                        "ExercisedEvent": {
                            "offset": 106,
                            "nodeId": 2,
                            "contractId": "004ef3ae401af384aa37391f3a975647b1ca3d9ca3dc97f7b1e19c47d013ed4956ca11122015cac2e81f6d2e2735ed64c16326230234cc374c85ed42657b7801bf62233ddc",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:LockedAmulet",
                            "interfaceId": null,
                            "choice": "LockedAmulet_Unlock",
                            "choiceArgument": {
                                "openRoundCid": "00c298815a41f51f7b6a164f7a2618e03b3caa2022a1919da05b2a4aa6400f40b4ca111220f7b646f00988b0a32aa21a5ab16f5962978b108c4ff37fcc944cdb7c40e56669"
                            },
                            "actingParties": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "consuming": true,
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "lastDescendantNodeId": 4,
                            "exerciseResult": {
                                "amuletSum": {
                                    "amulet": "004aaf5722cb10c5f59654017bcf346ba0c25838d020a79afa31b0235a58278cf0ca11122057178fb2d28c6b2563eef4035baf9e279b1f583ecc97a896fa7bd60b05ac324c",
                                    "amuletPrice": "0.0050000000",
                                    "round": {
                                        "number": "1"
                                    }
                                },
                                "meta": {
                                    "values": {
                                        "splice.lfdecentralizedtrust.org/reason": "holders released lock",
                                        "splice.lfdecentralizedtrust.org/tx-kind": "unlock"
                                    }
                                }
                            },
                            "packageName": "splice-amulet",
                            "implementedInterfaces": [
                                "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding"
                            ]
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 106,
                            "nodeId": 4,
                            "contractId": "004aaf5722cb10c5f59654017bcf346ba0c25838d020a79afa31b0235a58278cf0ca11122057178fb2d28c6b2563eef4035baf9e279b1f583ecc97a896fa7bd60b05ac324c",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "owner": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                "amount": {
                                    "initialAmount": "1064.0015220800",
                                    "createdAt": {
                                        "number": "1"
                                    },
                                    "ratePerRound": {
                                        "rate": "0.0038051800"
                                    }
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [
                                {
                                    "interfaceId": "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding",
                                    "viewStatus": {
                                        "code": 0,
                                        "message": "",
                                        "details": []
                                    },
                                    "viewValue": {
                                        "owner": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                        "instrumentId": {
                                            "admin": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                            "id": "Amulet"
                                        },
                                        "amount": "1064.0015220800",
                                        "lock": null,
                                        "meta": {
                                            "values": {
                                                "amulet.splice.lfdecentralizedtrust.org/created-in-round": "1",
                                                "amulet.splice.lfdecentralizedtrust.org/rate-per-round": "0.00380518"
                                            }
                                        }
                                    }
                                }
                            ],
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "signatories": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "observers": [],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "ExercisedEvent": {
                            "offset": 106,
                            "nodeId": 5,
                            "contractId": "001b1c0752079634f968fb59cdf0ec5b4aa9a085d939f1d443ca1b2a6d050e3927ca1112204b53a7228d1305d18dc568701cfdab4f60fc193d6c2e8e09c69582b2790e3550",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.AmuletRules:AmuletRules",
                            "interfaceId": null,
                            "choice": "AmuletRules_Transfer",
                            "choiceArgument": {
                                "transfer": {
                                    "sender": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                    "provider": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                    "inputs": [
                                        {
                                            "tag": "InputAmulet",
                                            "value": "004aaf5722cb10c5f59654017bcf346ba0c25838d020a79afa31b0235a58278cf0ca11122057178fb2d28c6b2563eef4035baf9e279b1f583ecc97a896fa7bd60b05ac324c"
                                        }
                                    ],
                                    "outputs": [
                                        {
                                            "receiver": "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87",
                                            "receiverFeeRatio": "0.0000000000",
                                            "amount": "1000.0000000000",
                                            "lock": null
                                        }
                                    ],
                                    "beneficiaries": null
                                },
                                "context": {
                                    "openMiningRound": "00c298815a41f51f7b6a164f7a2618e03b3caa2022a1919da05b2a4aa6400f40b4ca111220f7b646f00988b0a32aa21a5ab16f5962978b108c4ff37fcc944cdb7c40e56669",
                                    "issuingMiningRounds": [],
                                    "validatorRights": [],
                                    "featuredAppRight": null
                                },
                                "expectedDso": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9"
                            },
                            "actingParties": [
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "consuming": false,
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "lastDescendantNodeId": 12,
                            "exerciseResult": {
                                "round": {
                                    "number": "1"
                                },
                                "summary": {
                                    "inputAppRewardAmount": "0.0000000000",
                                    "inputValidatorRewardAmount": "0.0000000000",
                                    "inputSvRewardAmount": "0.0000000000",
                                    "inputAmuletAmount": "1064.0015220800",
                                    "balanceChanges": [
                                        [
                                            "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                            {
                                                "changeToInitialAmountAsOfRoundZero": "-1022.0000000000",
                                                "changeToHoldingFeesRate": "0.0000000000"
                                            }
                                        ],
                                        [
                                            "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87",
                                            {
                                                "changeToInitialAmountAsOfRoundZero": "1000.0038051800",
                                                "changeToHoldingFeesRate": "0.0038051800"
                                            }
                                        ]
                                    ],
                                    "holdingFees": "0.0000000000",
                                    "outputFees": ["16.0000000000"],
                                    "senderChangeFee": "6.0000000000",
                                    "senderChangeAmount": "42.0015220800",
                                    "amuletPrice": "0.0050000000",
                                    "inputValidatorFaucetAmount": "0.0000000000",
                                    "inputUnclaimedActivityRecordAmount": "0.0000000000"
                                },
                                "createdAmulets": [
                                    {
                                        "tag": "TransferResultAmulet",
                                        "value": "0026638a9b9db54fab1cc3f260b4db189a8e65e8bdaf646a66fdff3976a48e88a6ca1112209d4295be34eb089d5b94ed0c681723a2591681f09de55a95de8040c822726306"
                                    }
                                ],
                                "senderChangeAmulet": "009d1ed65f5ab6fb57fddf2de3671bc734807ec4aaba3f37b539388787e1adb250ca111220bed445fb61640859f9ed394ae51d029e2b5cd113c6df9bdd8633333ba1dfc8e8",
                                "meta": {
                                    "values": {
                                        "splice.lfdecentralizedtrust.org/burned": "22.0",
                                        "splice.lfdecentralizedtrust.org/sender": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                        "splice.lfdecentralizedtrust.org/tx-kind": "transfer"
                                    }
                                }
                            },
                            "packageName": "splice-amulet",
                            "implementedInterfaces": []
                        }
                    },
                    {
                        "ExercisedEvent": {
                            "offset": 106,
                            "nodeId": 8,
                            "contractId": "004aaf5722cb10c5f59654017bcf346ba0c25838d020a79afa31b0235a58278cf0ca11122057178fb2d28c6b2563eef4035baf9e279b1f583ecc97a896fa7bd60b05ac324c",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "interfaceId": null,
                            "choice": "Archive",
                            "choiceArgument": {},
                            "actingParties": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "consuming": true,
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "lastDescendantNodeId": 8,
                            "exerciseResult": {},
                            "packageName": "splice-amulet",
                            "implementedInterfaces": [
                                "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding"
                            ]
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 106,
                            "nodeId": 9,
                            "contractId": "0044b4793808d8844f63aae78e72c5e788eb07bf16a07fb56c02f32abde3b14f08ca111220467204e95f62b34f25d162934f48e36394b3a830b5602447d83cc5e22e0a5799",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:ValidatorRewardCoupon",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "user": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                "amount": "16.0000000000",
                                "round": {
                                    "number": "1"
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [],
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "signatories": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9"
                            ],
                            "observers": [
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 106,
                            "nodeId": 10,
                            "contractId": "00c0543921ee917ccd7d6453e0db4ff2b8264a703fc6df0bcd69100ac589ac05d8ca111220f71cb88db3445657a64288862aaba6c7b4f463366889ee036be182c632ede1ed",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:AppRewardCoupon",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "provider": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                "featured": false,
                                "amount": "16.0000000000",
                                "round": {
                                    "number": "1"
                                },
                                "beneficiary": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [],
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "signatories": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9"
                            ],
                            "observers": [
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 106,
                            "nodeId": 11,
                            "contractId": "0026638a9b9db54fab1cc3f260b4db189a8e65e8bdaf646a66fdff3976a48e88a6ca1112209d4295be34eb089d5b94ed0c681723a2591681f09de55a95de8040c822726306",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "owner": "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87",
                                "amount": {
                                    "initialAmount": "1000.0000000000",
                                    "createdAt": {
                                        "number": "1"
                                    },
                                    "ratePerRound": {
                                        "rate": "0.0038051800"
                                    }
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [
                                {
                                    "interfaceId": "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding",
                                    "viewStatus": {
                                        "code": 0,
                                        "message": "",
                                        "details": []
                                    },
                                    "viewValue": {
                                        "owner": "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87",
                                        "instrumentId": {
                                            "admin": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                            "id": "Amulet"
                                        },
                                        "amount": "1000.0000000000",
                                        "lock": null,
                                        "meta": {
                                            "values": {
                                                "amulet.splice.lfdecentralizedtrust.org/created-in-round": "1",
                                                "amulet.splice.lfdecentralizedtrust.org/rate-per-round": "0.00380518"
                                            }
                                        }
                                    }
                                }
                            ],
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "signatories": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "observers": [],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    },
                    {
                        "CreatedEvent": {
                            "offset": 106,
                            "nodeId": 12,
                            "contractId": "009d1ed65f5ab6fb57fddf2de3671bc734807ec4aaba3f37b539388787e1adb250ca111220bed445fb61640859f9ed394ae51d029e2b5cd113c6df9bdd8633333ba1dfc8e8",
                            "templateId": "6e9fc50fb94e56751b49f09ba2dc84da53a9d7cff08115ebb4f6b7a12d0c990c:Splice.Amulet:Amulet",
                            "contractKey": null,
                            "createArgument": {
                                "dso": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "owner": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                "amount": {
                                    "initialAmount": "42.0015220800",
                                    "createdAt": {
                                        "number": "1"
                                    },
                                    "ratePerRound": {
                                        "rate": "0.0038051800"
                                    }
                                }
                            },
                            "createdEventBlob": "",
                            "interfaceViews": [
                                {
                                    "interfaceId": "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding",
                                    "viewStatus": {
                                        "code": 0,
                                        "message": "",
                                        "details": []
                                    },
                                    "viewValue": {
                                        "owner": "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c",
                                        "instrumentId": {
                                            "admin": "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                            "id": "Amulet"
                                        },
                                        "amount": "42.0015220800",
                                        "lock": null,
                                        "meta": {
                                            "values": {
                                                "amulet.splice.lfdecentralizedtrust.org/created-in-round": "1",
                                                "amulet.splice.lfdecentralizedtrust.org/rate-per-round": "0.00380518"
                                            }
                                        }
                                    }
                                }
                            ],
                            "witnessParties": [
                                "treasury-party::12207bd11907b9b3c11ade702d30b556bfe635314d3d0f708f9677e09a4ff096ef87"
                            ],
                            "signatories": [
                                "DSO::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                                "sender::1220f37942af4f4d062006155d504f1adfa1565260cd499e62325b011c06db635d8c"
                            ],
                            "observers": [],
                            "createdAt": "1970-01-01T00:01:00Z",
                            "packageName": "splice-amulet"
                        }
                    }
                ],
                "offset": 106,
                "synchronizerId": "global-domain::1220d26d73867a428814de451fdd8e716acf45fe59c6569d76ad77d42270629f3ce9",
                "traceContext": {
                    "traceparent": "00-0e49990b26e75cc4ae47300de4607087-793c606077bad4e7-01",
                    "tracestate": null
                },
                "recordTime": "1970-01-01T00:01:00.000182Z"
            }
        }
    }
}

To parse this proceed as follows:

  1. Go over the list of events ordered by nodeId that you see in the transaction.

  2. Look for exercises of the TransferInstruction_Accept choice on the TransferInstruction interface. In the example, this is the event with node id 0. For each of those, extract the contract id. You can then query the event query service using:

    curl -sSL --fail-with-body http://json-api-url/v2/events/events-by-contract-id \
      -H 'Authorization: Bearer 00fc774936c91f423c117744102a5996e4dc117f2b6496ef337967a7d2c5d02e4aca1112203c35266c980ae19508cc690cb501f8c767c02bfdbe838f1f89105de6fe59439f' \
        -d '{
          "contractId": "009b939ae451ef1a0cb81d1606391406690e055b5be301fd2f51efb6be5675577eca1112200f58604ac538224f73bdc57117d73830ed1e3167f956d66f9e3ecdacbf2359a7",
          "eventFormat": {
            "filtersByParty": {
              "<treasury-party>": {
                "cumulative": [
                  {"identifierFilter": {"InterfaceFilter": {"value": {"interfaceId": "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferInstruction", "includeInterfaceView": true, "includeCreatedEventBlob": false}}}}
                ]
              }
            },
            "verbose": true
          }
        }'
    

    If you get a 404, the instruction is not for your treasury party so you can ignore it. If you get back an event, it has the same structure that we’ve seen above when a transfer offer is created and you can again extract the amount, instrument id and deposit account from it.

Differences between Multi-Step Deposits and Withdrawals

Analogously to 1-step transfers, the sender that creates the withdrawal offer, i.e., the treasury party sees a TransferFactory_Transfer exercise node and can extract amount and reason from that.

For Canton Coin, both the creation of the TransferInstruction as well as the acceptance currently charge fees so the amount specified in the transfer is smaller than the holdings change of the treasury party. Once the CIP for CC fee removal is implemented, this distinction goes away. Currently Canton Coin is the only token on Canton Network charging such fees.