Registry Utility - Allocation API Example

This example shows how to allocate assets for settlement execution on CNU 0.12.x and later, and then execute the transfer on that allocation. It uses:

  • Canton HTTP JSON API for ledger reads and command submission

  • The Registry Utility Token Standard backend (/api/token-standard/...) to obtain choice context

All scripts live in ./scripts/ and write their outputs as response-step-*.json files.

Preparation

Prerequisites:

  • Access to a running Canton HTTP JSON API and Registry Utility backend.

  • Local tools: bash, curl, jq, and uuidgen.

Add all the required information to source.sh:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## Purpose: Configurations for this example, amend variables as needed.
 5## Script: source.sh
 6## =================================================================================================
 7
 8# Operator details
 9OPERATOR_PARTY_ID="alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7"
10# You can retrieve the operator party ID from `http://<host>/api/utilities/v0/operator`, e.g.
11# - Local:  `curl http://localhost:8080/api/utilities/v0/operator`
12# - DevNet: `curl https://api.utilities.digitalasset-dev.com/api/utilities/v0/operator`
13
14# Instrument admin (or registrar) details whose instruments are being preapproved.
15ADMIN_PARTY_ID="admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389"
16ADMIN_USER_ID="admin"
17
18INSTRUMENT_ID="INST"
19AMOUNT="5.0"
20
21# Sender details
22SENDER_TOKEN="<PASTE_SENDER_JWT_HERE>"
23SENDER_PARTY_ID="sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
24SENDER_USER_ID="sender2"
25
26# Receiver details
27RECEIVER_TOKEN="<PASTE_RECEIVER_JWT_HERE>"
28RECEIVER_PARTY_ID="receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
29RECEIVER_USER_ID="receiver2"
30
31# Settler details
32# We let the receiver be the settler for simplicity, but it can be any party.
33EXECUTOR_TOKEN="<PASTE_EXECUTOR_JWT_HERE>"
34EXECUTOR_PARTY_ID="alice-lab-client4-operator::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
35EXECUTOR_USER_ID="alice-lab-client4-operator@clients"
36
37# JSON API endpoint
38# Example (local): HTTP_JSON_API="http://localhost:8001/api/json-api"
39# Example (remote): HTTP_JSON_API="https://<your-host>/api/json-api"
40# HTTP_JSON_API="http://localhost:8001/api/json-api"
41BACKEND_API="https://operator-utility-alice-lab-operator.vcluster.circus-dev.da-int.net/api/token-standard" # for token standard endpoints
42HTTP_JSON_API="https://utility-alice-lab-client4.vcluster.circus-dev.da-int.net/api/json-api"               # json api endpoint
43
44# Token standard holding interface, may change when new versions of splice exists
45ALLOCATIONFACTORY_INTERFACE="#splice-api-token-allocation-instruction-v1:Splice.Api.Token.AllocationInstructionV1:AllocationFactory"
46ALLOCATION_INTERFACE="#splice-api-token-allocation-v1:Splice.Api.Token.AllocationV1:Allocation"
47HOLDING_INTERFACE="#splice-api-token-holding-v1:Splice.Api.Token.HoldingV1:Holding"

The required information is:

Details of

Description

Sender

SENDER_TOKEN, SENDER_USER_ID, SENDER_PARTY_ID

Receiver

RECEIVER_TOKEN, RECEIVER_USER_ID, RECEIVER_PARTY_ID

Executor

EXECUTOR_TOKEN, EXECUTOR_USER_ID, EXECUTOR_PARTY_ID

Operator

OPERATOR_PARTY_ID

Instrument

ADMIN_PARTY_ID, INSTRUMENT_ID, AMOUNT

Endpoints

HTTP_JSON_API (JSON API base URL), BACKEND_API (token standard backend base URL)

Note

Allocation_ExecuteTransfer is jointly authorized by the sender, receiver, and executor.

For simplicity, this example assumes all three parties are hosted on the same participant node, and that the executor user has the required ActAs rights for each party it submits as.

That’s why the submission in step 8 includes:

"actAs":["${EXECUTOR_PARTY_ID}", "${SENDER_PARTY_ID}", "${RECEIVER_PARTY_ID}"]

If the executor is missing ActAs rights for any of these parties, the JSON API fails with a 403 “security-sensitive” error.

Step 1: Sender captures a ledger offset

Run:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## How-to Tutorial: Allocate asset for settlement execution
 5## Step 1: Retrieves the current ledger end offset from the ledger
 6## Authorized by: Sender
 7## Script: step-1-allocate.sh
 8## =================================================================================================
 9
10SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11DATAFILE="${SCRIPT_DIR}/source.sh"
12source "$DATAFILE"
13
14OFFSET=$(curl -sS --fail-with-body --request GET \
15    --url "${HTTP_JSON_API}/v2/state/ledger-end" \
16    --header "Accept: application/json" \
17    --header "Authorization: Bearer ${SENDER_TOKEN}")
18
19echo "$OFFSET" | jq
20
21OUTPUTFILE="${SCRIPT_DIR}/response-step-1.json"
22echo "$OFFSET" > "$OUTPUTFILE"

The result is the current ledger end offset, stored in response-step-1.json. For example:

1{
2    "offset": 15591
3}

Step 2: Sender queries unlocked holdings at that offset

Run:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## How-to Tutorial: Allocate asset for settlement execution
 5## Step 2: Retrieve sender's holdings as of the offset from step 1 to use for the allocation
 6## Authorized by: Sender
 7## Script: step-2-allocate.sh
 8## =================================================================================================
 9
10SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11DATAFILE="${SCRIPT_DIR}/source.sh"
12source "$DATAFILE"
13
14# Get offset from previous step
15if [[ -f "${SCRIPT_DIR}/response-step-1.json" ]]; then
16    JSONCONTENT=$(cat "${SCRIPT_DIR}/response-step-1.json")
17    OFFSET=$(echo "$JSONCONTENT" | jq -r '.offset // empty')
18    if [[ -z "${OFFSET}" || "${OFFSET}" == "null" ]]; then
19        echo "Error: response-step-1.json is missing a valid .offset" >&2
20        exit 1
21    fi
22else
23    echo "Error: response-step-1.json not found" >&2
24    exit 1
25fi
26
27RESULT=$(
28    curl -sS --fail-with-body \
29    --url "${HTTP_JSON_API}/v2/state/active-contracts" \
30    --header "Authorization: Bearer ${SENDER_TOKEN}" \
31    --header "Accept: application/json" \
32    --header "Content-Type: application/json" \
33    --request POST \
34    --data @- <<EOF
35{
36    "verbose": false,
37    "activeAtOffset": "${OFFSET}",
38    "filter": {
39        "filtersByParty": {
40            "${SENDER_PARTY_ID}": {
41                "cumulative": [{
42                    "identifierFilter": {
43                        "InterfaceFilter": {
44                            "value": {
45                                "interfaceId":"$HOLDING_INTERFACE",
46                                "includeInterfaceView": true,
47                                "includeCreatedEventBlob": false
48                            }
49                        }
50                    }
51                }]
52            }
53        }
54    }
55}
56EOF
57)
58
59# Filter holdings for a specific holder, instrument ID, admin and extract contractId
60HOLDINGCIDS=$(echo "$RESULT" | jq \
61    --arg SENDER_PARTY_ID "$SENDER_PARTY_ID" \
62    --arg INSTRUMENT_ID "$INSTRUMENT_ID" \
63    --arg ADMIN_PARTY_ID "$ADMIN_PARTY_ID" \
64    '[
65        .[] as $c
66        | $c.contractEntry.JsActiveContract.createdEvent.interfaceViews[]
67        | select(
68                .viewValue.owner == $SENDER_PARTY_ID and
69                .viewValue.instrumentId.id == $INSTRUMENT_ID and
70                .viewValue.instrumentId.admin == $ADMIN_PARTY_ID and
71                .viewValue.lock == null
72        )
73        | $c.contractEntry.JsActiveContract.createdEvent.contractId
74    ]'
75)
76
77if [[ "$(echo "$HOLDINGCIDS" | jq 'length')" -eq 0 ]]; then
78    echo "No holdings found for party=${SENDER_PARTY_ID} instrument=${ADMIN_PARTY_ID}:${INSTRUMENT_ID} at offset ${OFFSET}" >&2
79    exit 1
80fi
81
82echo "--- Holdings of sender (${SENDER_USER_ID}) as of offset ${OFFSET} ---"
83echo "$HOLDINGCIDS" | jq
84
85OUTPUTFILE="${SCRIPT_DIR}/response-step-2.json"
86echo "$HOLDINGCIDS" > "$OUTPUTFILE"

The result is a JSON array of Holding contract IDs, stored in response-step-2.json. For example:

1[
2  "00e3da3a42231c92d266cfaf79c4c3a2a49ae4ca16ac14b65399c9c89c2c33d49dca121220aeaf2a6f0d5a4bee0d1829060177ff1bd05c3a58a2732bc891f59ee07bea76c3"
3]

Step 3: Obtain choice context for AllocationFactory_Allocate (backend API)

This calls the token standard backend to construct a choice context and disclosed contracts.

Run:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## How-to Tutorial: Allocate asset for settlement execution
 5## Step 3: Get choice context for AllocationFactory_Allocate
 6## Authorized by: anyone
 7## Script: step-3-allocate.sh
 8## =================================================================================================
 9
10set -euo pipefail
11
12SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13DATAFILE="${SCRIPT_DIR}/source.sh"
14source "$DATAFILE"
15
16DATE_FORMAT='+%Y-%m-%dT%H:%M:%SZ'
17NOW_ISO_TIMESTAMP=$(date -u "$DATE_FORMAT")
18ONEHOUR_ISO_TIMESTAMP=$(date -u -d '+1 hour' "$DATE_FORMAT")
19TWOHOUR_ISO_TIMESTAMP=$(date -u -d '+2 hour' "$DATE_FORMAT")
20
21HOLDINGCIDS=$(cat "${SCRIPT_DIR}/response-step-2.json")
22
23RESULT=$(
24  curl -sS --fail-with-body \
25    --url "${BACKEND_API}/v0/registrars/${ADMIN_PARTY_ID}/registry/allocation-instruction/v1/allocation-factory" \
26    --header "Accept: application/json" \
27    --header "Content-Type: application/json" \
28    --request POST \
29    --data @- <<EOF
30{
31   "choiceArguments":{
32      "expectedAdmin":"${ADMIN_PARTY_ID}",
33      "allocation":{
34        "settlement":{
35          "executor":"$EXECUTOR_PARTY_ID",
36          "settlementRef":{
37            "id": "settlement-ref-123",
38            "cid": null
39          },
40          "requestedAt":"${NOW_ISO_TIMESTAMP}",
41          "allocateBefore":"${ONEHOUR_ISO_TIMESTAMP}",
42          "settleBefore":"${TWOHOUR_ISO_TIMESTAMP}",
43          "meta":{
44            "values": {}
45          }
46        },
47        "transferLegId":"transfer-leg-123",
48        "transferLeg":{
49          "sender":"$SENDER_PARTY_ID",
50          "receiver":"$RECEIVER_PARTY_ID",
51          "amount":"${AMOUNT}",
52          "instrumentId":{
53            "admin":"$ADMIN_PARTY_ID",
54            "id":"${INSTRUMENT_ID}"
55          },
56          "meta":{
57            "values": {}
58          }
59        }
60      },
61      "requestedAt":"${NOW_ISO_TIMESTAMP}",
62      "inputHoldingCids":${HOLDINGCIDS},
63      "extraArgs":{
64         "context":{
65          "values": {}
66         },
67         "meta":{
68          "values": {}
69         }
70      }
71   },
72   "excludeDebugFields":true
73}
74EOF
75)
76
77echo "--- Endpoint response ---"
78echo "$RESULT" | jq
79
80OUTPUTFILE="${SCRIPT_DIR}/response-step-3.json"
81echo "$RESULT" > "$OUTPUTFILE"

The result is stored in response-step-3.json. For example:

 1{
 2    "factoryId": "00459ff699b7f5d615df55589cff296cb5df23ca56b30647d6ca3edce7c49a83d0ca121220df02611c5ad7b85d993a00ea5376cdee09ecc78407c4207f5669652f9183e6d0",
 3    "choiceContext": {
 4        "choiceContextData": {
 5            "values": {
 6                "utility.digitalasset.com/instrument-configuration": {
 7                    "tag": "AV_ContractId",
 8                    "value": "00473fed86df9273817d431822c7fa962c56b189c57d3f10fc97d7ff414b1646dbca121220e5d05499ef66afcb63c38d53418d74629952012757bf900dc7a471fc3d6e723e"
 9                },
10                "utility.digitalasset.com/sender-credentials": {
11                    "tag": "AV_List",
12                    "value": [
13                        {
14                            "tag": "AV_ContractId",
15                            "value": "005b2eded970f1f43b8047998aef2b85e6b51d7944dc77862e82d8a11f9d7281d0ca12122059bc8a971c34f5b7786ff6b40dde5e4556531ac32326ed7293b509cf08261824"
16                        }
17                    ]
18                }
19            }
20        },
21        "disclosedContracts": [
22            {
23                "templateId": "aca349df9f3c0e61d8b3e5d3282f0e6e1c60d89a70c96d21ed36414fe8c13a6a:Utility.Registry.App.V0.Service.AllocationFactory:AllocationFactory",
24                "contractId": "00459ff699b7f5d615df55589cff296cb5df23ca56b30647d6ca3edce7c49a83d0ca121220df02611c5ad7b85d993a00ea5376cdee09ecc78407c4207f5669652f9183e6d0",
25                "createdEventBlob": "CgMyLjESqQYKRQBFn/aZt/XWFd9VWJz/KWy13yPKVrMGR9bKPtznxJqD0MoSEiDfAmEcWte4XZk6AOpTds3uCezHhAfEIH9WaWUvkYPm0BIXdXRpbGl0eS1yZWdpc3RyeS1hcHAtdjAajQEKQGFjYTM0OWRmOWYzYzBlNjFkOGIzZTVkMzI4MmYwZTZlMWM2MGQ4OWE3MGM5NmQyMWVkMzY0MTRmZThjMTNhNmESB1V0aWxpdHkSCFJlZ2lzdHJ5EgNBcHASAlYwEgdTZXJ2aWNlEhFBbGxvY2F0aW9uRmFjdG9yeRoRQWxsb2NhdGlvbkZhY3RvcnkiiAJqhQIKUgpQOk5wcm92aWRlcjo6MTIyMGQ4MTFlYWQ0MTljZDk5N2QxMDc5NGViN2M1ZmVlNzExNWQ1MmQyMGQ4NTYwNmQyZWI1YTliZGNjYmNlZjQwODgKTwpNOkthZG1pbjo6MTIyMDcyNDEwYmMxZjgxYjdlZjZhYmY5NTZmNDI0NTMxYzc0YTI5MTJkNDFkZGRlYjFjYTMzZGM4OWY4M2Q4MzQzODkKXgpcOlpmcmliZXJnLWxhYi1vcGVyYXRvcjo6MTIyMGI3ODU5OTQzYWM3NTVjMTIyNDkyZDFlNDlkZGMxZmNhMzc5NjY3ZWViOTZlY2I4ZjlhZTc0MmUzMjYwMmE4ZDcqS2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OSpOcHJvdmlkZXI6OjEyMjBkODExZWFkNDE5Y2Q5OTdkMTA3OTRlYjdjNWZlZTcxMTVkNTJkMjBkODU2MDZkMmViNWE5YmRjY2JjZWY0MDg4MlpmcmliZXJnLWxhYi1vcGVyYXRvcjo6MTIyMGI3ODU5OTQzYWM3NTVjMTIyNDkyZDFlNDlkZGMxZmNhMzc5NjY3ZWViOTZlY2I4ZjlhZTc0MmUzMjYwMmE4ZDc5wuUsO+tMBgBCKgomCiQIARIgBTqLeLdKcKFOvsSEfZSIZpAdm7m1fNU1Zq6yz77BjcQQHg==",
26                "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
27                "debugPackageName": null,
28                "debugPayload": null,
29                "debugCreatedAt": null
30            },
31            {
32                "templateId": "b83fe011748c9c0f07e0ad4c5bf72bfb6ca7a32296b5ec94cc615916aee30666:Utility.Registry.V0.Configuration.Instrument:InstrumentConfiguration",
33                "contractId": "00473fed86df9273817d431822c7fa962c56b189c57d3f10fc97d7ff414b1646dbca121220e5d05499ef66afcb63c38d53418d74629952012757bf900dc7a471fc3d6e723e",
34                "createdEventBlob": "CgMyLjESpwkKRQBHP+2G35JzgX1DGCLH+pYsVrGJxX0/EPyX1/9BSxZG28oSEiDl0FSZ72avy2PDjVNBjXRimVIBJ1e/kA3HpHH8PW5yPhITdXRpbGl0eS1yZWdpc3RyeS12MBqNAQpAYjgzZmUwMTE3NDhjOWMwZjA3ZTBhZDRjNWJmNzJiZmI2Y2E3YTMyMjk2YjVlYzk0Y2M2MTU5MTZhZWUzMDY2NhIHVXRpbGl0eRIIUmVnaXN0cnkSAlYwEg1Db25maWd1cmF0aW9uEgpJbnN0cnVtZW50GhdJbnN0cnVtZW50Q29uZmlndXJhdGlvbiKKBWqHBQpeClw6WmZyaWJlcmctbGFiLW9wZXJhdG9yOjoxMjIwYjc4NTk5NDNhYzc1NWMxMjI0OTJkMWU0OWRkYzFmY2EzNzk2NjdlZWI5NmVjYjhmOWFlNzQyZTMyNjAyYThkNwpSClA6TnByb3ZpZGVyOjoxMjIwZDgxMWVhZDQxOWNkOTk3ZDEwNzk0ZWI3YzVmZWU3MTE1ZDUyZDIwZDg1NjA2ZDJlYjVhOWJkY2NiY2VmNDA4OApPCk06S2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OQp8CnpqeApPCk06S2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OQoICgZCBElOU1QKGwoZQhdSZWdpc3RyYXJJbnRlcm5hbFNjaGVtZQoECgJaAAp9CntaeQp3anUKTwpNOkthZG1pbjo6MTIyMDcyNDEwYmMxZjgxYjdlZjZhYmY5NTZmNDI0NTMxYzc0YTI5MTJkNDFkZGRlYjFjYTMzZGM4OWY4M2Q4MzQzODkKIgogWh4KHGoaCg4KDEIKaXNJc3N1ZXJPZgoICgZCBElOU1QKfQp7WnkKd2p1Ck8KTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5CiIKIFoeChxqGgoOCgxCCmlzSG9sZGVyT2YKCAoGQgRJTlNUKkthZG1pbjo6MTIyMDcyNDEwYmMxZjgxYjdlZjZhYmY5NTZmNDI0NTMxYzc0YTI5MTJkNDFkZGRlYjFjYTMzZGM4OWY4M2Q4MzQzODkqTnByb3ZpZGVyOjoxMjIwZDgxMWVhZDQxOWNkOTk3ZDEwNzk0ZWI3YzVmZWU3MTE1ZDUyZDIwZDg1NjA2ZDJlYjVhOWJkY2NiY2VmNDA4ODJaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3ORCBkE3rTAYAQioKJgokCAESINP3jllGgJCRjyJ63mEcyVt+b5oy6xJ9x6y6Ra0uhoWjEB4=",
35                "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
36                "debugPackageName": null,
37                "debugPayload": null,
38                "debugCreatedAt": null
39            },
40            {
41                "templateId": "5a29ead611a0abd5f5b3fc3caf7d0f67c0ff802032ab6d392824aa9060e56d70:Utility.Credential.V0.Credential:Credential",
42                "contractId": "005b2eded970f1f43b8047998aef2b85e6b51d7944dc77862e82d8a11f9d7281d0ca12122059bc8a971c34f5b7786ff6b40dde5e4556531ac32326ed7293b509cf08261824",
43                "createdEventBlob": "CgMyLjESqwcKRQBbLt7ZcPH0O4BHmYrvK4XmtR15RNx3hi6C2KEfnXKB0MoSEiBZvIqXHDT1t3hv9rQN3l5FVlMawyMm7XKTtQnPCCYYJBIVdXRpbGl0eS1jcmVkZW50aWFsLXYwGnMKQDVhMjllYWQ2MTFhMGFiZDVmNWIzZmMzY2FmN2QwZjY3YzBmZjgwMjAzMmFiNmQzOTI4MjRhYTkwNjBlNTZkNzASB1V0aWxpdHkSCkNyZWRlbnRpYWwSAlYwEgpDcmVkZW50aWFsGgpDcmVkZW50aWFsIqgDaqUDCk8KTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5ClEKTzpNc2VuZGVyMjo6MTIyMGI2MmM5YjA2MDJkZDE4OGQyNDdlZjQxMjRmMTg0Yzk3ZDdmZmUyNTA1NzEyMjFhNzFjZDRjZDcyNWI0OWMxYjAKBQoDQgFhCgUKA0IBYQoECgJSAAoECgJSAAp1CnNacQpvam0KUQpPQk1zZW5kZXIyOjoxMjIwYjYyYzliMDYwMmRkMTg4ZDI0N2VmNDEyNGYxODRjOTdkN2ZmZTI1MDU3MTIyMWE3MWNkNGNkNzI1YjQ5YzFiMAoOCgxCCmlzSG9sZGVyT2YKCAoGQgRJTlNUCm4KbGpqCmgKZmJkCmIKXDpaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3EgIKACpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5Kk1zZW5kZXIyOjoxMjIwYjYyYzliMDYwMmRkMTg4ZDI0N2VmNDEyNGYxODRjOTdkN2ZmZTI1MDU3MTIyMWE3MWNkNGNkNzI1YjQ5YzFiMDJaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3OXXb/QMiTQYAQioKJgokCAESIBBJzVZA8YzxtAy9xeRSSFfXAojDemsfFYaUSe4WFKs+EB4=",
44                "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
45                "debugPackageName": null,
46                "debugPayload": null,
47                "debugCreatedAt": null
48            }
49        ]
50    }
51}

Step 4: Sender allocates assets (JSON API submit)

This submits an ExerciseCommand for AllocationFactory_Allocate as the sender.

Run:

  1#!/usr/bin/env bash
  2
  3## =================================================================================================
  4## How-to Tutorial: Allocate asset for settlement execution
  5## Step 4: Allocate asset for settlement execution
  6## Authorized by: Sender
  7## Script: step-4-allocate.sh
  8## =================================================================================================
  9
 10set -euo pipefail
 11
 12SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 13DATAFILE="${SCRIPT_DIR}/source.sh"
 14source "$DATAFILE"
 15
 16DATE_FORMAT='+%Y-%m-%dT%H:%M:%SZ'
 17NOW_ISO_TIMESTAMP=$(date -u "$DATE_FORMAT")
 18ONEHOUR_ISO_TIMESTAMP=$(date -u -d '+1 hour' "$DATE_FORMAT")
 19TWOHOUR_ISO_TIMESTAMP=$(date -u -d '+2 hour' "$DATE_FORMAT")
 20
 21HOLDINGCIDS=$(cat "${SCRIPT_DIR}/response-step-2.json")
 22
 23JSONCONTENT=$(cat "${SCRIPT_DIR}/response-step-3.json")
 24FACTORYID=$(jq -c -e '.factoryId' "${SCRIPT_DIR}/response-step-3.json")
 25CHOICECONTEXTDATA=$(jq -c -e '.choiceContext.choiceContextData' "${SCRIPT_DIR}/response-step-3.json")
 26DISCLOSEDCONTRACTS=$(jq -c -e '.choiceContext.disclosedContracts' "${SCRIPT_DIR}/response-step-3.json")
 27
 28RESULT=$(
 29  curl -sS --fail-with-body \
 30  --url "${HTTP_JSON_API}/v2/commands/submit-and-wait-for-transaction" \
 31  --header "Authorization: Bearer ${SENDER_TOKEN}" \
 32  --header "Accept: application/json" \
 33    --header "Content-Type: application/json" \
 34    --request POST \
 35    --data @- <<EOF
 36{
 37   "commands":{
 38        "commands":[
 39            {
 40                "ExerciseCommand":{
 41                    "templateId":"${ALLOCATIONFACTORY_INTERFACE}",
 42                    "contractId":${FACTORYID},
 43                    "choice":"AllocationFactory_Allocate",
 44                    "choiceArgument":{
 45                        "expectedAdmin":"${ADMIN_PARTY_ID}",
 46                        "allocation":{
 47                          "settlement":{
 48                            "executor":"$EXECUTOR_PARTY_ID",
 49                            "settlementRef":{
 50                              "id": "settlement-ref-123",
 51                              "cid": null
 52                            },
 53                            "requestedAt":"${NOW_ISO_TIMESTAMP}",
 54                            "allocateBefore":"${ONEHOUR_ISO_TIMESTAMP}",
 55                            "settleBefore":"${TWOHOUR_ISO_TIMESTAMP}",
 56                            "meta":{
 57                              "values": {}
 58                            }
 59                          },
 60                          "transferLegId":"transfer-leg-123",
 61                          "transferLeg":{
 62                            "sender":"$SENDER_PARTY_ID",
 63                            "receiver":"$RECEIVER_PARTY_ID",
 64                            "amount":"${AMOUNT}",
 65                            "instrumentId":{
 66                              "admin":"$ADMIN_PARTY_ID",
 67                              "id":"${INSTRUMENT_ID}"
 68                            },
 69                            "meta":{
 70                              "values": {}
 71                            }
 72                          }
 73                        },
 74                        "requestedAt":"${NOW_ISO_TIMESTAMP}",
 75                        "inputHoldingCids":${HOLDINGCIDS},
 76                        "extraArgs":{
 77                            "context":${CHOICECONTEXTDATA},
 78                            "meta":{
 79                                "values":{
 80                                }
 81                            }
 82                        }
 83                    }
 84                }
 85            }
 86        ],
 87        "workflowId":"",
 88        "userId":"${SENDER_USER_ID}",
 89        "commandId":"$(uuidgen | tr -d '\n')",
 90        "deduplicationPeriod":{
 91            "DeduplicationDuration":{
 92                "value":{
 93                    "seconds":30,
 94                    "nanos":0
 95                }
 96            }
 97        },
 98        "actAs":[
 99          "${SENDER_PARTY_ID}"
100        ],
101        "readAs":[
102
103        ],
104        "submissionId":"$(uuidgen | tr -d '\n')",
105        "disclosedContracts": ${DISCLOSEDCONTRACTS},
106        "domainId":"",
107        "packageIdSelectionPreference":[]
108    }
109}
110EOF
111)
112
113echo "--- Command response ---"
114echo "$RESULT" | jq
115
116OUTPUTFILE="${SCRIPT_DIR}/response-step-4.json"
117echo "$RESULT" > "$OUTPUTFILE"

The result is stored in response-step-4.json. For example:

  1{
  2    "transaction": {
  3        "updateId": "122074e607dda508cc52347eef99bda11b7a0e7ecb6fecd441f7418151bc67b71ec9",
  4        "commandId": "B0865FA7-2DBD-4AA6-8583-240F09AA0C25",
  5        "workflowId": "",
  6        "effectiveAt": "2026-03-16T12:08:29.501624Z",
  7        "events": [
  8            {
  9                "ArchivedEvent": {
 10                    "offset": 15594,
 11                    "nodeId": 5,
 12                    "contractId": "00e3da3a42231c92d266cfaf79c4c3a2a49ae4ca16ac14b65399c9c89c2c33d49dca121220aeaf2a6f0d5a4bee0d1829060177ff1bd05c3a58a2732bc891f59ee07bea76c3",
 13                    "templateId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1:Utility.Registry.Holding.V0.Holding:Holding",
 14                    "witnessParties": [
 15                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
 16                    ],
 17                    "packageName": "utility-registry-holding-v0",
 18                    "implementedInterfaces": []
 19                }
 20            },
 21            {
 22                "CreatedEvent": {
 23                    "offset": 15594,
 24                    "nodeId": 6,
 25                    "contractId": "006262cb6efeaca5816d5abc30d35ceb041488a6e4a9c57aa0465ee1973de56c01ca1212200d0ee16d168e394b3e6d717f352536513dfa52ab1dcdaba65a0718537dd8524e",
 26                    "templateId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1:Utility.Registry.Holding.V0.Holding:Holding",
 27                    "contractKey": null,
 28                    "createArgument": {
 29                        "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
 30                        "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
 31                        "registrar": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 32                        "owner": "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
 33                        "instrument": {
 34                            "source": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 35                            "id": "INST",
 36                            "scheme": "RegistrarInternalScheme"
 37                        },
 38                        "label": "",
 39                        "amount": "5.0000000000",
 40                        "lock": {
 41                            "lockers": {
 42                                "map": [
 43                                    [
 44                                        "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 45                                        {}
 46                                    ]
 47                                ]
 48                            },
 49                            "context": "Allocation Reference {id = \"settlement-ref-123\", cid = None};\"transfer-leg-123\""
 50                        }
 51                    },
 52                    "createdEventBlob": "",
 53                    "interfaceViews": [],
 54                    "witnessParties": [
 55                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
 56                    ],
 57                    "signatories": [
 58                        "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 59                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
 60                    ],
 61                    "observers": [
 62                        "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
 63                        "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088"
 64                    ],
 65                    "createdAt": "2026-03-16T12:08:29.501624Z",
 66                    "packageName": "utility-registry-holding-v0",
 67                    "representativePackageId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1",
 68                    "acsDelta": true
 69                }
 70            },
 71            {
 72                "CreatedEvent": {
 73                    "offset": 15594,
 74                    "nodeId": 7,
 75                    "contractId": "0019003538e5cbfd47ca8cf8c1a0f83c4ea76002f4e0e6f6571f99be16f889a6f7ca12122096b810898f5a75188de928168fe2964a0e4b41945f0b6634735a1d4bf2db740b",
 76                    "templateId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1:Utility.Registry.Holding.V0.Holding:Holding",
 77                    "contractKey": null,
 78                    "createArgument": {
 79                        "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
 80                        "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
 81                        "registrar": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 82                        "owner": "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
 83                        "instrument": {
 84                            "source": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 85                            "id": "INST",
 86                            "scheme": "RegistrarInternalScheme"
 87                        },
 88                        "label": "",
 89                        "amount": "5.0000000000"
 90                    },
 91                    "createdEventBlob": "",
 92                    "interfaceViews": [],
 93                    "witnessParties": [
 94                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
 95                    ],
 96                    "signatories": [
 97                        "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 98                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
 99                    ],
100                    "observers": [
101                        "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
102                        "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088"
103                    ],
104                    "createdAt": "2026-03-16T12:08:29.501624Z",
105                    "packageName": "utility-registry-holding-v0",
106                    "representativePackageId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1",
107                    "acsDelta": true
108                }
109            },
110            {
111                "CreatedEvent": {
112                    "offset": 15594,
113                    "nodeId": 8,
114                    "contractId": "0008823d0b4ac25185541dfb51a4c88ae4265978e01528c19caf92beeb2e3d0a78ca121220c2688c57a3a53ee243783bf0f824534a6c14e487a0f2b1cd5deddac0ab99b2d0",
115                    "templateId": "b83fe011748c9c0f07e0ad4c5bf72bfb6ca7a32296b5ec94cc615916aee30666:Utility.Registry.V0.Holding.Allocation:DvpLegAllocation",
116                    "contractKey": null,
117                    "createArgument": {
118                        "allocation": {
119                            "settlement": {
120                                "executor": "alice-lab-client4-operator::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
121                                "settlementRef": {
122                                    "id": "settlement-ref-123"
123                                },
124                                "requestedAt": "2026-03-16T12:08:29Z",
125                                "allocateBefore": "2026-03-16T13:08:29Z",
126                                "settleBefore": "2026-03-16T14:08:29Z",
127                                "meta": {
128                                    "values": {}
129                                }
130                            },
131                            "transferLegId": "transfer-leg-123",
132                            "transferLeg": {
133                                "sender": "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
134                                "receiver": "receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
135                                "amount": "5.0000000000",
136                                "instrumentId": {
137                                    "admin": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
138                                    "id": "INST"
139                                },
140                                "meta": {
141                                    "values": {}
142                                }
143                            }
144                        },
145                        "lockedHoldingCid": "006262cb6efeaca5816d5abc30d35ceb041488a6e4a9c57aa0465ee1973de56c01ca1212200d0ee16d168e394b3e6d717f352536513dfa52ab1dcdaba65a0718537dd8524e",
146                        "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
147                        "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088"
148                    },
149                    "createdEventBlob": "",
150                    "interfaceViews": [],
151                    "witnessParties": [
152                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
153                    ],
154                    "signatories": [
155                        "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
156                        "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
157                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
158                    ],
159                    "observers": [
160                        "alice-lab-client4-operator::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
161                        "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7"
162                    ],
163                    "createdAt": "2026-03-16T12:08:29.501624Z",
164                    "packageName": "utility-registry-v0",
165                    "representativePackageId": "b83fe011748c9c0f07e0ad4c5bf72bfb6ca7a32296b5ec94cc615916aee30666",
166                    "acsDelta": true
167                }
168            }
169        ],
170        "offset": 15594,
171        "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
172        "traceContext": {
173            "traceparent": "00-200371022ae22c2a8ffd0b2d5923f2a5-2963d1bf4a662e7c-01",
174            "tracestate": null
175        },
176        "recordTime": "2026-03-16T12:08:30.358670Z",
177        "externalTransactionHash": null
178    }
179}

Step 5: Executor captures a ledger offset

Run:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## How-to Tutorial: Allocate asset for settlement execution
 5## Step 5: Retrieves the current ledger end offset from the ledger
 6## Authorized by: Executor
 7## Script: step-5-allocation-execute.sh
 8## =================================================================================================
 9
10set -euo pipefail
11
12SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13DATAFILE="${SCRIPT_DIR}/source.sh"
14source "$DATAFILE"
15
16OFFSET=$(curl -sS --fail-with-body \
17    --url "${HTTP_JSON_API}/v2/state/ledger-end" \
18    --header "Accept: application/json" \
19    --header "Authorization: Bearer ${EXECUTOR_TOKEN}")
20
21echo "$OFFSET" | jq
22
23OUTPUTFILE="${SCRIPT_DIR}/response-step-5.json"
24echo "$OFFSET" > "$OUTPUTFILE"

The result is stored in response-step-5.json. For example:

1{
2    "offset": 15607
3}

Step 6: Executor finds the allocation contract ID

This queries active contracts at the executor offset and filters for allocations matching: executor, sender, receiver, instrument admin+id.

Run:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## How-to Tutorial: Allocate asset for settlement execution
 5## Step 6: Get the allocation to settle
 6## Authorized by: Executor
 7## Script: step-6-allocation-execute.sh
 8## =================================================================================================
 9
10SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11DATAFILE="${SCRIPT_DIR}/source.sh"
12source "$DATAFILE"
13
14# Get offset from previous step
15if [[ -f "${SCRIPT_DIR}/response-step-5.json" ]]; then
16  JSONCONTENT=$(cat "${SCRIPT_DIR}/response-step-5.json")
17  OFFSET=$(echo "$JSONCONTENT" | jq -r ".offset")
18else
19  echo "Error: response-step-5.json not found"
20  exit 1
21fi
22
23RESULT=$(
24    curl -sS --fail-with-body \
25    --url "${HTTP_JSON_API}/v2/state/active-contracts" \
26    --header "Authorization: Bearer ${EXECUTOR_TOKEN}" \
27    --header "Accept: application/json" \
28    --header "Content-Type: application/json" \
29    --request POST \
30    --data @- <<EOF
31{
32    "verbose": false,
33    "activeAtOffset": "${OFFSET}",
34    "filter": {
35        "filtersByParty": {
36            "${EXECUTOR_PARTY_ID}": {
37                "cumulative": [{
38                    "identifierFilter": {
39                        "InterfaceFilter": {
40                            "value": {
41                                "interfaceId":"$ALLOCATION_INTERFACE",
42                                "includeInterfaceView": true,
43                                "includeCreatedEventBlob": false
44                            }
45                        }
46                    }
47                }]
48            }
49        }
50    }
51}
52EOF
53)
54
55# Filter allocations and pick the first matching contractId
56ALLOCATIONCIDS=$(echo "$RESULT" | jq -c \
57    --arg EXECUTOR_PARTY_ID "$EXECUTOR_PARTY_ID" \
58    --arg INSTRUMENT_ID "$INSTRUMENT_ID" \
59    --arg ADMIN_PARTY_ID "$ADMIN_PARTY_ID" \
60    --arg SENDER_PARTY_ID "$SENDER_PARTY_ID" \
61    --arg RECEIVER_PARTY_ID "$RECEIVER_PARTY_ID" \
62    --arg EXECUTOR_PARTY_ID "$EXECUTOR_PARTY_ID" \
63    '[
64      .[] as $c
65      | $c.contractEntry.JsActiveContract.createdEvent.interfaceViews[]
66      | select(
67          .viewValue.allocation.settlement.executor == $EXECUTOR_PARTY_ID and
68          .viewValue.allocation.transferLeg.instrumentId.id == $INSTRUMENT_ID and
69          .viewValue.allocation.transferLeg.instrumentId.admin == $ADMIN_PARTY_ID and
70          .viewValue.allocation.transferLeg.sender == $SENDER_PARTY_ID and
71          .viewValue.allocation.transferLeg.receiver == $RECEIVER_PARTY_ID
72      )
73      | $c.contractEntry.JsActiveContract.createdEvent.contractId
74    ]'
75)
76
77if [[ -z "$ALLOCATIONCIDS" ]]; then
78    echo "Error: no matching allocation found for executor ${EXECUTOR_PARTY_ID} at offset ${OFFSET}" >&2
79    exit 1
80fi
81
82echo "--- Allocation of executor (${EXECUTOR_USER_ID}) as of offset ${OFFSET} ---"
83echo "$ALLOCATIONCIDS" | jq
84
85OUTPUTFILE="${SCRIPT_DIR}/response-step-6.json"
86echo "$ALLOCATIONCIDS" > "$OUTPUTFILE"

The result is a JSON array of Allocation contract IDs, stored in response-step-6.json. For example:

1[
2    "0008823d0b4ac25185541dfb51a4c88ae4265978e01528c19caf92beeb2e3d0a78ca121220c2688c57a3a53ee243783bf0f824534a6c14e487a0f2b1cd5deddac0ab99b2d0"
3]

Step 7: Obtain choice context for Allocation_ExecuteTransfer (backend API)

Run:

 1#!/usr/bin/env bash
 2
 3## =================================================================================================
 4## How-to Tutorial: Allocate asset for settlement execution
 5## Step 7: Get choice context for Allocation_ExecuteTransfer
 6## Authorized by: anyone
 7## Script: step-7-allocation-execute.sh
 8## =================================================================================================
 9
10set -euo pipefail
11
12trap 'echo "ERROR: step-7-allocation-execute.sh failed at line $LINENO" >&2' ERR
13
14SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15DATAFILE="${SCRIPT_DIR}/source.sh"
16source "$DATAFILE"
17
18DATE_FORMAT='+%Y-%m-%dT%H:%M:%SZ'
19NOW_ISO_TIMESTAMP=$(date -u "$DATE_FORMAT")
20ONEHOUR_ISO_TIMESTAMP=$(date -u -d '+1 hour' "$DATE_FORMAT")
21TWOHOUR_ISO_TIMESTAMP=$(date -u -d '+2 hour' "$DATE_FORMAT")
22
23# response-step-6.json is a JSON array of allocation contractIds; pick the first.
24ALLOCATIONCID=$(jq -r -e '.[0] // empty' "${SCRIPT_DIR}/response-step-6.json")
25if [[ -z "$ALLOCATIONCID" ]]; then
26    echo "Error: response-step-6.json contains no allocation CIDs" >&2
27    exit 1
28fi
29
30OUTPUTFILE="${SCRIPT_DIR}/response-step-7.json"
31URL="${BACKEND_API}/v0/registrars/${ADMIN_PARTY_ID}/registry/allocations/v1/${ALLOCATIONCID}/choice-contexts/execute-transfer"
32
33if ! curl -sS --fail-with-body \
34  --url "$URL" \
35  --header "Accept: application/json" \
36  --header "Content-Type: application/json" \
37  --request POST \
38  --output "$OUTPUTFILE" \
39  --data @- <<EOF
40{
41   "excludeDebugFields":true
42}
43EOF
44then
45  echo "ERROR: HTTP request failed." >&2
46  echo "URL: $URL" >&2
47  echo "Response body saved to: $OUTPUTFILE" >&2
48  if [[ -s "$OUTPUTFILE" ]]; then
49    echo "--- Response body ---" >&2
50    cat "$OUTPUTFILE" >&2
51    echo >&2
52  fi
53  exit 1
54fi
55
56RESULT=$(cat "$OUTPUTFILE")
57
58echo "--- Endpoint response ---"
59echo "$RESULT" | jq

The result is stored in response-step-7.json.

Step 8: Executor executes the transfer (JSON API submit)

This submits Allocation_ExecuteTransfer against the first allocation CID in response-step-6.json. It uses the executor user and token, and includes the disclosed contracts from step 7. For example:

  1{
  2    "choiceContextData": {
  3        "values": {
  4            "utility.digitalasset.com/instrument-configuration": {
  5                "tag": "AV_ContractId",
  6                "value": "00473fed86df9273817d431822c7fa962c56b189c57d3f10fc97d7ff414b1646dbca121220e5d05499ef66afcb63c38d53418d74629952012757bf900dc7a471fc3d6e723e"
  7            },
  8            "utility.digitalasset.com/sender-credentials": {
  9                "tag": "AV_List",
 10                "value": [
 11                    {
 12                        "tag": "AV_ContractId",
 13                        "value": "005b2eded970f1f43b8047998aef2b85e6b51d7944dc77862e82d8a11f9d7281d0ca12122059bc8a971c34f5b7786ff6b40dde5e4556531ac32326ed7293b509cf08261824"
 14                    }
 15                ]
 16            },
 17            "utility.digitalasset.com/receiver-credentials": {
 18                "tag": "AV_List",
 19                "value": [
 20                    {
 21                        "tag": "AV_ContractId",
 22                        "value": "00be4c34445ecb704351fa0f37d1f3546bcf106c4ededa5d37285f96607002abdfca12122037a6d5b2c1921ba29ef32dca6d3b6c44fe95d05520119253c3163c3effda8278"
 23                    }
 24                ]
 25            },
 26            "utility.digitalasset.com/transfer-rule": {
 27                "tag": "AV_ContractId",
 28                "value": "00ec16b655604462f7e2dad3986befed5d235d83b0c4f9dcb111443c57dcafe4b7ca1212203b7dbc24a59feb8eeb99c3eba76db87cf11e23eea761b72454127cdd3ea04f94"
 29            }
 30        }
 31    },
 32    "disclosedContracts": [
 33        {
 34            "templateId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1:Utility.Registry.Holding.V0.Holding:Holding",
 35            "contractId": "006262cb6efeaca5816d5abc30d35ceb041488a6e4a9c57aa0465ee1973de56c01ca1212200d0ee16d168e394b3e6d717f352536513dfa52ab1dcdaba65a0718537dd8524e",
 36            "createdEventBlob": "CgMyLjESkAoKRQBiYstu/qylgW1avDDTXOsEFIim5KnFeqBGXuGXPeVsAcoSEiANDuFtFo45Sz5tcX81JTZRPfpSqx3Nq6ZaBxhTfdhSThIbdXRpbGl0eS1yZWdpc3RyeS1ob2xkaW5nLXYwGnQKQDgxMDc4OTlhYzQ3MjNjZTk4NmJmN2QyNzQxNjUzNGU1NzZlNTRiOTIxNjFlNDYxNTBhNTk1ZmI3OGZmM2QzYTESB1V0aWxpdHkSCFJlZ2lzdHJ5EgdIb2xkaW5nEgJWMBIHSG9sZGluZxoHSG9sZGluZyK2BWqzBQpeClw6WmZyaWJlcmctbGFiLW9wZXJhdG9yOjoxMjIwYjc4NTk5NDNhYzc1NWMxMjI0OTJkMWU0OWRkYzFmY2EzNzk2NjdlZWI5NmVjYjhmOWFlNzQyZTMyNjAyYThkNwpSClA6TnByb3ZpZGVyOjoxMjIwZDgxMWVhZDQxOWNkOTk3ZDEwNzk0ZWI3YzVmZWU3MTE1ZDUyZDIwZDg1NjA2ZDJlYjVhOWJkY2NiY2VmNDA4OApPCk06S2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OQpRCk86TXNlbmRlcjI6OjEyMjBiNjJjOWIwNjAyZGQxODhkMjQ3ZWY0MTI0ZjE4NGM5N2Q3ZmZlMjUwNTcxMjIxYTcxY2Q0Y2Q3MjViNDljMWIwCnwKemp4Ck8KTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5CggKBkIESU5TVAobChlCF1JlZ2lzdHJhckludGVybmFsU2NoZW1lCgQKAkIAChAKDjIMNS4wMDAwMDAwMDAwCsIBCr8BUrwBCrkBarYBCl8KXWpbClkKV2JVClMKTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5EgIKAApTClFCT0FsbG9jYXRpb24gUmVmZXJlbmNlIHtpZCA9ICJzZXR0bGVtZW50LXJlZi0xMjMiLCBjaWQgPSBOb25lfTsidHJhbnNmZXItbGVnLTEyMyIqS2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OSpNc2VuZGVyMjo6MTIyMGI2MmM5YjA2MDJkZDE4OGQyNDdlZjQxMjRmMTg0Yzk3ZDdmZmUyNTA1NzEyMjFhNzFjZDRjZDcyNWI0OWMxYjAyWmZyaWJlcmctbGFiLW9wZXJhdG9yOjoxMjIwYjc4NTk5NDNhYzc1NWMxMjI0OTJkMWU0OWRkYzFmY2EzNzk2NjdlZWI5NmVjYjhmOWFlNzQyZTMyNjAyYThkNzJOcHJvdmlkZXI6OjEyMjBkODExZWFkNDE5Y2Q5OTdkMTA3OTRlYjdjNWZlZTcxMTVkNTJkMjBkODU2MDZkMmViNWE5YmRjY2JjZWY0MDg4ObgQrBMjTQYAQioKJgokCAESIMgZ+QVfY5aT8qx/jh4dgxirOSNZfj721shn2FNDEKZiEB4=",
 37            "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
 38            "debugPackageName": "utility-registry-holding-v0",
 39            "debugPayload": {
 40                "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
 41                "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
 42                "registrar": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 43                "owner": "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
 44                "instrument": {
 45                    "source": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 46                    "id": "INST",
 47                    "scheme": "RegistrarInternalScheme"
 48                },
 49                "label": "",
 50                "amount": "5.0000000000",
 51                "lock": {
 52                    "lockers": {
 53                        "map": [
 54                            [
 55                                "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 56                                {}
 57                            ]
 58                        ]
 59                    },
 60                    "context": "Allocation Reference {id = \"settlement-ref-123\", cid = None};\"transfer-leg-123\"",
 61                    "observers": null
 62                }
 63            },
 64            "debugCreatedAt": "2026-03-16T12:08:29.501Z"
 65        },
 66        {
 67            "templateId": "b83fe011748c9c0f07e0ad4c5bf72bfb6ca7a32296b5ec94cc615916aee30666:Utility.Registry.V0.Configuration.Instrument:InstrumentConfiguration",
 68            "contractId": "00473fed86df9273817d431822c7fa962c56b189c57d3f10fc97d7ff414b1646dbca121220e5d05499ef66afcb63c38d53418d74629952012757bf900dc7a471fc3d6e723e",
 69            "createdEventBlob": "CgMyLjESpwkKRQBHP+2G35JzgX1DGCLH+pYsVrGJxX0/EPyX1/9BSxZG28oSEiDl0FSZ72avy2PDjVNBjXRimVIBJ1e/kA3HpHH8PW5yPhITdXRpbGl0eS1yZWdpc3RyeS12MBqNAQpAYjgzZmUwMTE3NDhjOWMwZjA3ZTBhZDRjNWJmNzJiZmI2Y2E3YTMyMjk2YjVlYzk0Y2M2MTU5MTZhZWUzMDY2NhIHVXRpbGl0eRIIUmVnaXN0cnkSAlYwEg1Db25maWd1cmF0aW9uEgpJbnN0cnVtZW50GhdJbnN0cnVtZW50Q29uZmlndXJhdGlvbiKKBWqHBQpeClw6WmZyaWJlcmctbGFiLW9wZXJhdG9yOjoxMjIwYjc4NTk5NDNhYzc1NWMxMjI0OTJkMWU0OWRkYzFmY2EzNzk2NjdlZWI5NmVjYjhmOWFlNzQyZTMyNjAyYThkNwpSClA6TnByb3ZpZGVyOjoxMjIwZDgxMWVhZDQxOWNkOTk3ZDEwNzk0ZWI3YzVmZWU3MTE1ZDUyZDIwZDg1NjA2ZDJlYjVhOWJkY2NiY2VmNDA4OApPCk06S2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OQp8CnpqeApPCk06S2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OQoICgZCBElOU1QKGwoZQhdSZWdpc3RyYXJJbnRlcm5hbFNjaGVtZQoECgJaAAp9CntaeQp3anUKTwpNOkthZG1pbjo6MTIyMDcyNDEwYmMxZjgxYjdlZjZhYmY5NTZmNDI0NTMxYzc0YTI5MTJkNDFkZGRlYjFjYTMzZGM4OWY4M2Q4MzQzODkKIgogWh4KHGoaCg4KDEIKaXNJc3N1ZXJPZgoICgZCBElOU1QKfQp7WnkKd2p1Ck8KTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5CiIKIFoeChxqGgoOCgxCCmlzSG9sZGVyT2YKCAoGQgRJTlNUKkthZG1pbjo6MTIyMDcyNDEwYmMxZjgxYjdlZjZhYmY5NTZmNDI0NTMxYzc0YTI5MTJkNDFkZGRlYjFjYTMzZGM4OWY4M2Q4MzQzODkqTnByb3ZpZGVyOjoxMjIwZDgxMWVhZDQxOWNkOTk3ZDEwNzk0ZWI3YzVmZWU3MTE1ZDUyZDIwZDg1NjA2ZDJlYjVhOWJkY2NiY2VmNDA4ODJaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3ORCBkE3rTAYAQioKJgokCAESINP3jllGgJCRjyJ63mEcyVt+b5oy6xJ9x6y6Ra0uhoWjEB4=",
 70            "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
 71            "debugPackageName": "utility-registry-v0",
 72            "debugPayload": {
 73                "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
 74                "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
 75                "registrar": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 76                "defaultIdentifier": {
 77                    "source": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 78                    "id": "INST",
 79                    "scheme": "RegistrarInternalScheme"
 80                },
 81                "additionalIdentifiers": [],
 82                "issuerRequirements": [
 83                    {
 84                        "issuer": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 85                        "requiredClaims": [
 86                            {
 87                                "_1": "isIssuerOf",
 88                                "_2": "INST"
 89                            }
 90                        ]
 91                    }
 92                ],
 93                "holderRequirements": [
 94                    {
 95                        "issuer": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
 96                        "requiredClaims": [
 97                            {
 98                                "_1": "isHolderOf",
 99                                "_2": "INST"
100                            }
101                        ]
102                    }
103                ],
104                "providerAppRewardBeneficiaries": null
105            },
106            "debugCreatedAt": "2026-03-14T07:31:00.69Z"
107        },
108        {
109            "templateId": "b83fe011748c9c0f07e0ad4c5bf72bfb6ca7a32296b5ec94cc615916aee30666:Utility.Registry.V0.Rule.Transfer:TransferRule",
110            "contractId": "00ec16b655604462f7e2dad3986befed5d235d83b0c4f9dcb111443c57dcafe4b7ca1212203b7dbc24a59feb8eeb99c3eba76db87cf11e23eea761b72454127cdd3ea04f94",
111            "createdEventBlob": "CgMyLjESjgYKRQDsFrZVYERi9+La05hr7+1dI12DsMT53LERRDxX3K/kt8oSEiA7fbwkpZ/rjuuZw+unbbh88R4j7qdhtyRUEnzdPqBPlBITdXRpbGl0eS1yZWdpc3RyeS12MBp3CkBiODNmZTAxMTc0OGM5YzBmMDdlMGFkNGM1YmY3MmJmYjZjYTdhMzIyOTZiNWVjOTRjYzYxNTkxNmFlZTMwNjY2EgdVdGlsaXR5EghSZWdpc3RyeRICVjASBFJ1bGUSCFRyYW5zZmVyGgxUcmFuc2ZlclJ1bGUiiAJqhQIKXgpcOlpmcmliZXJnLWxhYi1vcGVyYXRvcjo6MTIyMGI3ODU5OTQzYWM3NTVjMTIyNDkyZDFlNDlkZGMxZmNhMzc5NjY3ZWViOTZlY2I4ZjlhZTc0MmUzMjYwMmE4ZDcKUgpQOk5wcm92aWRlcjo6MTIyMGQ4MTFlYWQ0MTljZDk5N2QxMDc5NGViN2M1ZmVlNzExNWQ1MmQyMGQ4NTYwNmQyZWI1YTliZGNjYmNlZjQwODgKTwpNOkthZG1pbjo6MTIyMDcyNDEwYmMxZjgxYjdlZjZhYmY5NTZmNDI0NTMxYzc0YTI5MTJkNDFkZGRlYjFjYTMzZGM4OWY4M2Q4MzQzODkqS2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OSpOcHJvdmlkZXI6OjEyMjBkODExZWFkNDE5Y2Q5OTdkMTA3OTRlYjdjNWZlZTcxMTVkNTJkMjBkODU2MDZkMmViNWE5YmRjY2JjZWY0MDg4MlpmcmliZXJnLWxhYi1vcGVyYXRvcjo6MTIyMGI3ODU5OTQzYWM3NTVjMTIyNDkyZDFlNDlkZGMxZmNhMzc5NjY3ZWViOTZlY2I4ZjlhZTc0MmUzMjYwMmE4ZDc5wuUsO+tMBgBCKgomCiQIARIg04nxvq1s1ZZkjDiWxsWtRHhx9LR3GN+RGUUFafnkF9YQHg==",
112            "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
113            "debugPackageName": "utility-registry-v0",
114            "debugPayload": {
115                "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
116                "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
117                "registrar": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389"
118            },
119            "debugCreatedAt": "2026-03-14T07:31:00.69Z"
120        },
121        {
122            "templateId": "5a29ead611a0abd5f5b3fc3caf7d0f67c0ff802032ab6d392824aa9060e56d70:Utility.Credential.V0.Credential:Credential",
123            "contractId": "005b2eded970f1f43b8047998aef2b85e6b51d7944dc77862e82d8a11f9d7281d0ca12122059bc8a971c34f5b7786ff6b40dde5e4556531ac32326ed7293b509cf08261824",
124            "createdEventBlob": "CgMyLjESqwcKRQBbLt7ZcPH0O4BHmYrvK4XmtR15RNx3hi6C2KEfnXKB0MoSEiBZvIqXHDT1t3hv9rQN3l5FVlMawyMm7XKTtQnPCCYYJBIVdXRpbGl0eS1jcmVkZW50aWFsLXYwGnMKQDVhMjllYWQ2MTFhMGFiZDVmNWIzZmMzY2FmN2QwZjY3YzBmZjgwMjAzMmFiNmQzOTI4MjRhYTkwNjBlNTZkNzASB1V0aWxpdHkSCkNyZWRlbnRpYWwSAlYwEgpDcmVkZW50aWFsGgpDcmVkZW50aWFsIqgDaqUDCk8KTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5ClEKTzpNc2VuZGVyMjo6MTIyMGI2MmM5YjA2MDJkZDE4OGQyNDdlZjQxMjRmMTg0Yzk3ZDdmZmUyNTA1NzEyMjFhNzFjZDRjZDcyNWI0OWMxYjAKBQoDQgFhCgUKA0IBYQoECgJSAAoECgJSAAp1CnNacQpvam0KUQpPQk1zZW5kZXIyOjoxMjIwYjYyYzliMDYwMmRkMTg4ZDI0N2VmNDEyNGYxODRjOTdkN2ZmZTI1MDU3MTIyMWE3MWNkNGNkNzI1YjQ5YzFiMAoOCgxCCmlzSG9sZGVyT2YKCAoGQgRJTlNUCm4KbGpqCmgKZmJkCmIKXDpaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3EgIKACpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5Kk1zZW5kZXIyOjoxMjIwYjYyYzliMDYwMmRkMTg4ZDI0N2VmNDEyNGYxODRjOTdkN2ZmZTI1MDU3MTIyMWE3MWNkNGNkNzI1YjQ5YzFiMDJaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3OXXb/QMiTQYAQioKJgokCAESIBBJzVZA8YzxtAy9xeRSSFfXAojDemsfFYaUSe4WFKs+EB4=",
125            "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
126            "debugPackageName": "utility-credential-v0",
127            "debugPayload": {
128                "issuer": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
129                "holder": "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
130                "id": "a",
131                "description": "a",
132                "validFrom": null,
133                "validUntil": null,
134                "claims": [
135                    {
136                        "subject": "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
137                        "property": "isHolderOf",
138                        "value": "INST"
139                    }
140                ],
141                "observers": {
142                    "map": [
143                        [
144                            "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
145                            {}
146                        ]
147                    ]
148                }
149            },
150            "debugCreatedAt": "2026-03-16T10:52:31.459Z"
151        },
152        {
153            "templateId": "5a29ead611a0abd5f5b3fc3caf7d0f67c0ff802032ab6d392824aa9060e56d70:Utility.Credential.V0.Credential:Credential",
154            "contractId": "00be4c34445ecb704351fa0f37d1f3546bcf106c4ededa5d37285f96607002abdfca12122037a6d5b2c1921ba29ef32dca6d3b6c44fe95d05520119253c3163c3effda8278",
155            "createdEventBlob": "CgMyLjESsQcKRQC+TDREXstwQ1H6DzfR81RrzxBsTt7aXTcoX5ZgcAKr38oSEiA3ptWywZIbop7zLcptO2xE/pXQVSARklPDFjw+/9qCeBIVdXRpbGl0eS1jcmVkZW50aWFsLXYwGnMKQDVhMjllYWQ2MTFhMGFiZDVmNWIzZmMzY2FmN2QwZjY3YzBmZjgwMjAzMmFiNmQzOTI4MjRhYTkwNjBlNTZkNzASB1V0aWxpdHkSCkNyZWRlbnRpYWwSAlYwEgpDcmVkZW50aWFsGgpDcmVkZW50aWFsIqwDaqkDCk8KTTpLYWRtaW46OjEyMjA3MjQxMGJjMWY4MWI3ZWY2YWJmOTU2ZjQyNDUzMWM3NGEyOTEyZDQxZGRkZWIxY2EzM2RjODlmODNkODM0Mzg5ClMKUTpPcmVjZWl2ZXIyOjoxMjIwYjYyYzliMDYwMmRkMTg4ZDI0N2VmNDEyNGYxODRjOTdkN2ZmZTI1MDU3MTIyMWE3MWNkNGNkNzI1YjQ5YzFiMAoFCgNCAWEKBQoDQgFhCgQKAlIACgQKAlIACncKdVpzCnFqbwpTClFCT3JlY2VpdmVyMjo6MTIyMGI2MmM5YjA2MDJkZDE4OGQyNDdlZjQxMjRmMTg0Yzk3ZDdmZmUyNTA1NzEyMjFhNzFjZDRjZDcyNWI0OWMxYjAKDgoMQgppc0hvbGRlck9mCggKBkIESU5TVApuCmxqagpoCmZiZApiClw6WmZyaWJlcmctbGFiLW9wZXJhdG9yOjoxMjIwYjc4NTk5NDNhYzc1NWMxMjI0OTJkMWU0OWRkYzFmY2EzNzk2NjdlZWI5NmVjYjhmOWFlNzQyZTMyNjAyYThkNxICCgAqS2FkbWluOjoxMjIwNzI0MTBiYzFmODFiN2VmNmFiZjk1NmY0MjQ1MzFjNzRhMjkxMmQ0MWRkZGViMWNhMzNkYzg5ZjgzZDgzNDM4OSpPcmVjZWl2ZXIyOjoxMjIwYjYyYzliMDYwMmRkMTg4ZDI0N2VmNDEyNGYxODRjOTdkN2ZmZTI1MDU3MTIyMWE3MWNkNGNkNzI1YjQ5YzFiMDJaZnJpYmVyZy1sYWItb3BlcmF0b3I6OjEyMjBiNzg1OTk0M2FjNzU1YzEyMjQ5MmQxZTQ5ZGRjMWZjYTM3OTY2N2VlYjk2ZWNiOGY5YWU3NDJlMzI2MDJhOGQ3OYN2RwYiTQYAQioKJgokCAESIKeiNdPW2m5IGwm9fk4CSKL1dAvpTh/5jpyq5aXIiwsTEB4=",
156            "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
157            "debugPackageName": "utility-credential-v0",
158            "debugPayload": {
159                "issuer": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
160                "holder": "receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
161                "id": "a",
162                "description": "a",
163                "validFrom": null,
164                "validUntil": null,
165                "claims": [
166                    {
167                        "subject": "receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
168                        "property": "isHolderOf",
169                        "value": "INST"
170                    }
171                ],
172                "observers": {
173                    "map": [
174                        [
175                            "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
176                            {}
177                        ]
178                    ]
179                }
180            },
181            "debugCreatedAt": "2026-03-16T10:53:09.837Z"
182        }
183    ]
184}

Run:

  1#!/usr/bin/env bash
  2
  3## =================================================================================================
  4## How-to Tutorial: Allocate asset for settlement execution
  5## Step 8: Execute the transfer on the allocation
  6## Authorized by: Executor, Sender, and Receiver
  7## Script: step-8-allocation-execute.sh
  8## =================================================================================================
  9
 10set -euo pipefail
 11
 12trap 'echo "ERROR: step-8-allocation-execute.sh failed at line $LINENO" >&2' ERR
 13
 14SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 15DATAFILE="${SCRIPT_DIR}/source.sh"
 16source "$DATAFILE"
 17
 18DATE_FORMAT='+%Y-%m-%dT%H:%M:%SZ'
 19NOW_ISO_TIMESTAMP=$(date -u "$DATE_FORMAT")
 20ONEHOUR_ISO_TIMESTAMP=$(date -u -d '+1 hour' "$DATE_FORMAT")
 21TWOHOUR_ISO_TIMESTAMP=$(date -u -d '+2 hour' "$DATE_FORMAT")
 22
 23if [[ ! -f "${SCRIPT_DIR}/response-step-6.json" ]]; then
 24    echo "Error: response-step-6.json not found" >&2
 25    exit 1
 26fi
 27if [[ ! -f "${SCRIPT_DIR}/response-step-7.json" ]]; then
 28    echo "Error: response-step-7.json not found" >&2
 29    exit 1
 30fi
 31
 32# response-step-6.json is a JSON array of allocation contractIds; pick the first.
 33# Keep it as JSON (quoted) so it can be embedded safely into the request body.
 34ALLOCATIONCID_JSON=$(jq -c -e '.[0] // empty' "${SCRIPT_DIR}/response-step-6.json")
 35if [[ -z "$ALLOCATIONCID_JSON" ]]; then
 36    echo "Error: response-step-6.json contains no allocation CIDs" >&2
 37    exit 1
 38fi
 39
 40JSONCONTENT=$(cat "${SCRIPT_DIR}/response-step-7.json")
 41CHOICECONTEXTDATA=$(jq -c -e '(.choiceContext.choiceContextData // .choiceContextData)' <<<"$JSONCONTENT")
 42DISCLOSEDCONTRACTS=$(jq -c -e '(.choiceContext.disclosedContracts // .disclosedContracts)' <<<"$JSONCONTENT")
 43
 44# Preflight: ensure the submitting user has CanActAs for all actAs parties.
 45ACT_AS_PARTIES=("$EXECUTOR_PARTY_ID" "$SENDER_PARTY_ID" "$RECEIVER_PARTY_ID")
 46if ! RIGHTS_JSON=$(curl -sS --fail-with-body \
 47    --url "${HTTP_JSON_API}/v2/users/${EXECUTOR_USER_ID}/rights" \
 48    --header "Authorization: Bearer ${EXECUTOR_TOKEN}" \
 49    --header "Accept: application/json"); then
 50    echo "ERROR: Failed to fetch rights for ${EXECUTOR_USER_ID} from JSON API." >&2
 51    exit 1
 52fi
 53
 54MISSING_ACT_AS=()
 55for party in "${ACT_AS_PARTIES[@]}"; do
 56    if ! jq -e --arg party "$party" '.rights[]? | select(.kind.CanActAs.value.party? == $party)' >/dev/null <<<"$RIGHTS_JSON"; then
 57        MISSING_ACT_AS+=("$party")
 58    fi
 59done
 60
 61if [[ ${#MISSING_ACT_AS[@]} -gt 0 ]]; then
 62    echo "ERROR: ${EXECUTOR_USER_ID} is missing CanActAs rights for one or more parties in actAs:" >&2
 63    printf '  - %s\n' "${MISSING_ACT_AS[@]}" >&2
 64    echo "Hint: this often happens when RECEIVER_PARTY_ID/SENDER_PARTY_ID values don't match the parties the token was granted rights for." >&2
 65    exit 1
 66fi
 67
 68OUTPUTFILE="${SCRIPT_DIR}/response-step-8.json"
 69
 70# NOTE: Don't use command substitution for curl here.
 71# In bash, `set -e` doesn't reliably abort on failures inside `var=$(...)`.
 72if ! curl -sS --fail-with-body \
 73    --url "${HTTP_JSON_API}/v2/commands/submit-and-wait-for-transaction" \
 74    --header "Authorization: Bearer ${EXECUTOR_TOKEN}" \
 75    --header "Accept: application/json" \
 76    --header "Content-Type: application/json" \
 77    --request POST \
 78    --output "$OUTPUTFILE" \
 79    --data @- <<EOF
 80{
 81   "commands":{
 82        "commands":[
 83            {
 84                "ExerciseCommand":{
 85                    "templateId":"${ALLOCATION_INTERFACE}",
 86                    "contractId":${ALLOCATIONCID_JSON},
 87                    "choice":"Allocation_ExecuteTransfer",
 88                    "choiceArgument":{
 89                        "extraArgs":{
 90                            "context":${CHOICECONTEXTDATA},
 91                            "meta":{
 92                                "values": {}
 93                            }
 94                        }
 95                    }
 96                }
 97            }
 98        ],
 99        "workflowId":"",
100        "userId":"${EXECUTOR_USER_ID}",
101        "commandId":"$(uuidgen | tr -d '\n')",
102        "deduplicationPeriod":{
103            "DeduplicationDuration":{
104                "value":{
105                    "seconds":30,
106                    "nanos":0
107                }
108            }
109        },
110        "actAs":[
111            "${EXECUTOR_PARTY_ID}",
112            "${SENDER_PARTY_ID}",
113            "${RECEIVER_PARTY_ID}"
114        ],
115        "readAs":[
116
117        ],
118        "submissionId":"$(uuidgen | tr -d '\n')",
119        "disclosedContracts": ${DISCLOSEDCONTRACTS},
120        "domainId":"",
121        "packageIdSelectionPreference":[]
122    }
123}
124EOF
125then
126    echo "ERROR: HTTP request failed." >&2
127    echo "Response body saved to: $OUTPUTFILE" >&2
128    if [[ -s "$OUTPUTFILE" ]]; then
129        echo "--- Response body ---" >&2
130        cat "$OUTPUTFILE" >&2
131        echo >&2
132    fi
133    exit 1
134fi
135
136RESULT=$(cat "$OUTPUTFILE")
137
138# The JSON API can return a JSON error object with HTTP 200 in some setups.
139# Treat those as failures so the script doesn't appear to succeed.
140if ! echo "$RESULT" | jq -e '(
141    (has("code") and .code == "NA")
142    or has("error")
143    or has("error_description")
144 ) | not' >/dev/null; then
145    echo "ERROR: JSON API returned an error payload. See ${OUTPUTFILE}" >&2
146    echo "$RESULT" | jq >&2
147    exit 1
148fi
149
150echo "--- Command response ---"
151echo "$RESULT" | jq

The result is stored in response-step-8.json. For example:

 1{
 2    "transaction": {
 3        "updateId": "1220f8aeeb5fd609ab464ace0c701c25f8a47cb2e25f4a80e2c24a4440440cf56f44",
 4        "commandId": "C399C4C9-5773-418A-8E4E-1524A0D470E3",
 5        "workflowId": "",
 6        "effectiveAt": "2026-03-16T12:12:16.225422Z",
 7        "events": [
 8            {
 9                "ArchivedEvent": {
10                    "offset": 15610,
11                    "nodeId": 0,
12                    "contractId": "0008823d0b4ac25185541dfb51a4c88ae4265978e01528c19caf92beeb2e3d0a78ca121220c2688c57a3a53ee243783bf0f824534a6c14e487a0f2b1cd5deddac0ab99b2d0",
13                    "templateId": "b83fe011748c9c0f07e0ad4c5bf72bfb6ca7a32296b5ec94cc615916aee30666:Utility.Registry.V0.Holding.Allocation:DvpLegAllocation",
14                    "witnessParties": [
15                        "alice-lab-client4-operator::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
16                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
17                    ],
18                    "packageName": "utility-registry-v0",
19                    "implementedInterfaces": []
20                }
21            },
22            {
23                "ArchivedEvent": {
24                    "offset": 15610,
25                    "nodeId": 6,
26                    "contractId": "006262cb6efeaca5816d5abc30d35ceb041488a6e4a9c57aa0465ee1973de56c01ca1212200d0ee16d168e394b3e6d717f352536513dfa52ab1dcdaba65a0718537dd8524e",
27                    "templateId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1:Utility.Registry.Holding.V0.Holding:Holding",
28                    "witnessParties": [
29                        "sender2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
30                    ],
31                    "packageName": "utility-registry-holding-v0",
32                    "implementedInterfaces": []
33                }
34            },
35            {
36                "CreatedEvent": {
37                    "offset": 15610,
38                    "nodeId": 7,
39                    "contractId": "002b123f29edac03dc421bc177fe9f5ca0bd7957d114c81e63f611f135bc945cb4ca121220c14d12e76d5c7d8967b814a2d18c41cbd7af2065f487c715c5e5751088aa65cf",
40                    "templateId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1:Utility.Registry.Holding.V0.Holding:Holding",
41                    "contractKey": null,
42                    "createArgument": {
43                        "operator": "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
44                        "provider": "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088",
45                        "registrar": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
46                        "owner": "receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0",
47                        "instrument": {
48                            "source": "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
49                            "id": "INST",
50                            "scheme": "RegistrarInternalScheme"
51                        },
52                        "label": "",
53                        "amount": "5.0000000000"
54                    },
55                    "createdEventBlob": "",
56                    "interfaceViews": [],
57                    "witnessParties": [
58                        "receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
59                    ],
60                    "signatories": [
61                        "admin::122072410bc1f81b7ef6abf956f424531c74a2912d41dddeb1ca33dc89f83d834389",
62                        "receiver2::1220b62c9b0602dd188d247ef4124f184c97d7ffe250571221a71cd4cd725b49c1b0"
63                    ],
64                    "observers": [
65                        "alice-lab-operator::1220b7859943ac755c122492d1e49ddc1fca379667eeb96ecb8f9ae742e32602a8d7",
66                        "provider::1220d811ead419cd997d10794eb7c5fee7115d52d20d85606d2eb5a9bdccbcef4088"
67                    ],
68                    "createdAt": "2026-03-16T12:12:16.225422Z",
69                    "packageName": "utility-registry-holding-v0",
70                    "representativePackageId": "8107899ac4723ce986bf7d27416534e576e54b92161e46150a595fb78ff3d3a1",
71                    "acsDelta": true
72                }
73            }
74        ],
75        "offset": 15610,
76        "synchronizerId": "global-domain::12206cf8e1c0ce67d82d961490f1ec392f67c13bd48be571eeefbfa7834a587a6127",
77        "traceContext": {
78            "traceparent": "00-8d3f0457309050da1aba351968e209f4-a4b4cd7268930307-01",
79            "tracestate": null
80        },
81        "recordTime": "2026-03-16T12:12:15.895453Z",
82        "externalTransactionHash": null
83    }
84}

Note

If step 8 fails with HTTP 403 and a security-sensitive error payload, it usually means the JSON API cannot authorize the actAs parties that the script submits.

The script submits with:

  • actAs: executor party + sender party + receiver party

So ${EXECUTOR_USER_ID} must have CanActAs rights for all those parties (not just CanReadAs). You can inspect rights with by running ./scripts/check.sh.