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:
JavaScript/TypeScript: use the token standard history parser provided in the wallet SDK.
Java/JVM: use the the Java TransactionParser from the https://github.com/digital-asset/ex-java-json-api-bindings repository as a blueprint.
Other languages: use the Java TransactionParser referenced above as a blueprint.
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:
Go over the list of events ordered by
nodeId
that you see in the transaction.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 withnodeId
4 which exercises theTransferPreapproval_Send
choice. Note that this choice is specific to Canton Coin so rely on the existence of themeta
field which is standardized instead of the specific choice name.Extract the
"splice.lfdecentralizedtrust.org/reason"
to get the deposit account. In this example it isdeposit-account-id
.Go over all events whose
nodeId
is larger than thenodeId
of the transfer (4 in the example here) and smaller than thelastDescendantNodeId
of the transfer (12 in the example here).Find all
CreatedEvents
in that range that create aHolding
with"owner": "<treasury-party>"
and sum up the amounts for eachinstrumentId
. 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 created200.0000000000
for the token with instrument id{"admin": "DSO::12204b8b621ec1dedd51ee2510085f8164cad194953496494d32f541f3f2c170e962", "id": "Amulet"}
.Find all
ExercisedEvents
withimplementedInterfaces
containing theHolding
interface andconsuming: true
. In the example here, this is the event withnodeId:: 8
. For each of them get thecontractId
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 } }'
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.Continue with the events starting at node id
lastDescendantNodeId + 1
. Note that in this example this skips over the event withnodeId: 5
which exercisesAmuletRules_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:
Go over the list of events ordered by
nodeId
that you see in the transaction.Look for all
CreatedEvents
of theTransferInstruction
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 id0
. Extract theinstrument
, theamount
and thesplice.lfdecentralizedtrust.org/reason
field from theinterfaceView
and the contract id of theTransferInstruction
. 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:
Go over the list of events ordered by
nodeId
that you see in the transaction.Look for exercises of the
TransferInstruction_Accept
choice on theTransferInstruction
interface. In the example, this is the event with node id0
. 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.