@settlemint/dalp-cli 3.1.33-main.43208452773 → 3.1.33-main.43226609968

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9551,6 +9551,108 @@
9551
9551
  }
9552
9552
  ]
9553
9553
  },
9554
+ "bankRail/clientLinkDecision": {
9555
+ "name": "bankRail/clientLinkDecision",
9556
+ "method": "POST",
9557
+ "url": "/api/v2/bank-rail/connections/{connectionId}/client-links/{clientLinkId}/decisions",
9558
+ "summary": "Decide a client's delivery request",
9559
+ "description": "Approves or rejects the link's open delivery request, named by its approval id, with an optional reason. `approve` reads the gateway again and switches delivery to it; it is refused with `delivery-stale`, after closing the request and raising a case, when the gateway or a check no longer matches the request. `reject` keeps the client's credits minting to its wallet. The manager who opened the request cannot decide it (`same-actor`). Refused with `state` when the request is no longer open.",
9560
+ "help": "Approves or rejects the link's open delivery request, named by its approval id, with an optional reason. `approve` reads the gateway again and switches delivery to it; it is refused with `delivery-stale`, after closing the request and raising a case, when the gateway or a check no longer matches the request. `reject` keeps the client's credits minting to its wallet. The manager who opened the request cannot decide it (`same-actor`). Refused with `state` when the request is no longer open.",
9561
+ "tags": [
9562
+ "Bank rail"
9563
+ ],
9564
+ "pathParams": [
9565
+ {
9566
+ "name": "connectionId",
9567
+ "in": "path",
9568
+ "required": true,
9569
+ "description": null,
9570
+ "type": "string",
9571
+ "enum": null,
9572
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|[fF]{8}-[fF]{4}-[fF]{4}-[fF]{4}-[fF]{12})$",
9573
+ "examples": [],
9574
+ "fields": []
9575
+ },
9576
+ {
9577
+ "name": "clientLinkId",
9578
+ "in": "path",
9579
+ "required": true,
9580
+ "description": null,
9581
+ "type": "string",
9582
+ "enum": null,
9583
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|[fF]{8}-[fF]{4}-[fF]{4}-[fF]{4}-[fF]{12})$",
9584
+ "examples": [],
9585
+ "fields": []
9586
+ }
9587
+ ],
9588
+ "queryParams": [],
9589
+ "headerParams": [
9590
+ {
9591
+ "name": "Idempotency-Key",
9592
+ "in": "header",
9593
+ "required": false,
9594
+ "description": "Retry key for one mutation. Reuse it only for the same method, path, and body on a route that documents replay safety. If omitted, the platform generates a UUIDv7 key; replay-safe writes echo it in the `Idempotency-Key` response header. A lost response still requires status reconciliation.",
9595
+ "type": "string",
9596
+ "enum": null,
9597
+ "pattern": null,
9598
+ "examples": [],
9599
+ "fields": []
9600
+ }
9601
+ ],
9602
+ "requestBodyDescription": "Approves or rejects the link's open delivery request. An approval reads the gateway again and sets delivery to the gateway only when every check still passes; a rejection keeps the client's credits minting to its wallet.",
9603
+ "hasRequestBody": true,
9604
+ "bodyIsComplex": false,
9605
+ "bodyFields": [
9606
+ {
9607
+ "name": "decision",
9608
+ "in": "query",
9609
+ "required": true,
9610
+ "description": null,
9611
+ "type": "string",
9612
+ "enum": [
9613
+ "approve",
9614
+ "reject"
9615
+ ],
9616
+ "pattern": null,
9617
+ "examples": [
9618
+ "approve",
9619
+ "reject"
9620
+ ],
9621
+ "fields": []
9622
+ },
9623
+ {
9624
+ "name": "approvalId",
9625
+ "in": "query",
9626
+ "required": true,
9627
+ "description": "The link's open delivery request.",
9628
+ "type": "string",
9629
+ "enum": null,
9630
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|[fF]{8}-[fF]{4}-[fF]{4}-[fF]{4}-[fF]{12})$",
9631
+ "examples": [],
9632
+ "fields": []
9633
+ },
9634
+ {
9635
+ "name": "reason",
9636
+ "in": "query",
9637
+ "required": false,
9638
+ "description": "Why the request is decided, kept on the approval.",
9639
+ "type": "string",
9640
+ "enum": null,
9641
+ "pattern": null,
9642
+ "examples": [],
9643
+ "fields": []
9644
+ }
9645
+ ],
9646
+ "examples": [
9647
+ {
9648
+ "description": "Approves or rejects the link's open delivery request, named by its approval id, with an optional reason. `approve` reads the gateway again and switches delivery to it; it is refused with `delivery-stale`, after closing the request and raising a case, when the gateway or a check no longer matches the request. `reject` keeps the client's credits minting to its wallet. The manager who opened the request cannot decide it (`same-actor`). Refused with `state` when the request is no longer open.",
9649
+ "path": {
9650
+ "connectionId": "<connectionId>",
9651
+ "clientLinkId": "<clientLinkId>"
9652
+ }
9653
+ }
9654
+ ]
9655
+ },
9554
9656
  "bankRail/clientLinkDelete": {
9555
9657
  "name": "bankRail/clientLinkDelete",
9556
9658
  "method": "DELETE",
@@ -9613,6 +9715,68 @@
9613
9715
  }
9614
9716
  ]
9615
9717
  },
9718
+ "bankRail/clientLinkTransition": {
9719
+ "name": "bankRail/clientLinkTransition",
9720
+ "method": "POST",
9721
+ "url": "/api/v2/bank-rail/connections/{connectionId}/client-links/{clientLinkId}/transitions",
9722
+ "summary": "Switch a client's credit delivery",
9723
+ "description": "`enable-gateway-delivery` reads the client's custody gateway, runs the delivery checks and opens a delivery request that another bank rail manager decides; it names the link's rowVersion. It is refused with `booked-mode` when the connection books credits without minting, `preconditions-failed` when a check fails, `delivery-request-open` when a request is already open and `row-version` when the link moved, and answers a retryable 503 when the gateway cannot be read. `disable-gateway-delivery` sends the client's future credits back to its wallet at once and withdraws an open delivery request. It names the link's rowVersion; a replay that finds the link already delivering to the wallet returns it unchanged. Credits whose mint already settled keep delivering.",
9724
+ "help": "`enable-gateway-delivery` reads the client's custody gateway, runs the delivery checks and opens a delivery request that another bank rail manager decides; it names the link's rowVersion. It is refused with `booked-mode` when the connection books credits without minting, `preconditions-failed` when a check fails, `delivery-request-open` when a request is already open and `row-version` when the link moved, and answers a retryable 503 when the gateway cannot be read. `disable-gateway-delivery` sends the client's future credits back to its wallet at once and withdraws an open delivery request. It names the link's rowVersion; a replay that finds the link already delivering to the wallet returns it unchanged. Credits whose mint already settled keep delivering.",
9725
+ "tags": [
9726
+ "Bank rail"
9727
+ ],
9728
+ "pathParams": [
9729
+ {
9730
+ "name": "connectionId",
9731
+ "in": "path",
9732
+ "required": true,
9733
+ "description": null,
9734
+ "type": "string",
9735
+ "enum": null,
9736
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|[fF]{8}-[fF]{4}-[fF]{4}-[fF]{4}-[fF]{12})$",
9737
+ "examples": [],
9738
+ "fields": []
9739
+ },
9740
+ {
9741
+ "name": "clientLinkId",
9742
+ "in": "path",
9743
+ "required": true,
9744
+ "description": null,
9745
+ "type": "string",
9746
+ "enum": null,
9747
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|[fF]{8}-[fF]{4}-[fF]{4}-[fF]{4}-[fF]{12})$",
9748
+ "examples": [],
9749
+ "fields": []
9750
+ }
9751
+ ],
9752
+ "queryParams": [],
9753
+ "headerParams": [
9754
+ {
9755
+ "name": "Idempotency-Key",
9756
+ "in": "header",
9757
+ "required": false,
9758
+ "description": "Retry key for one mutation. Reuse it only for the same method, path, and body on a route that documents replay safety. If omitted, the platform generates a UUIDv7 key; replay-safe writes echo it in the `Idempotency-Key` response header. A lost response still requires status reconciliation.",
9759
+ "type": "string",
9760
+ "enum": null,
9761
+ "pattern": null,
9762
+ "examples": [],
9763
+ "fields": []
9764
+ }
9765
+ ],
9766
+ "requestBodyDescription": "enable-gateway-delivery reads the client's gateway and, when every check passes, opens a request another bank rail manager decides; the client's credits keep minting to its wallet until then. disable-gateway-delivery sends the client's future credits back to its wallet at once and withdraws an open delivery request. Credits whose mint already settled keep delivering.",
9767
+ "hasRequestBody": true,
9768
+ "bodyIsComplex": true,
9769
+ "bodyFields": [],
9770
+ "examples": [
9771
+ {
9772
+ "description": "`enable-gateway-delivery` reads the client's custody gateway, runs the delivery checks and opens a delivery request that another bank rail manager decides; it names the link's rowVersion. It is refused with `booked-mode` when the connection books credits without minting, `preconditions-failed` when a check fails, `delivery-request-open` when a request is already open and `row-version` when the link moved, and answers a retryable 503 when the gateway cannot be read. `disable-gateway-delivery` sends the client's future credits back to its wallet at once and withdraws an open delivery request. It names the link's rowVersion; a replay that finds the link already delivering to the wallet returns it unchanged. Credits whose mint already settled keep delivering.",
9773
+ "path": {
9774
+ "connectionId": "<connectionId>",
9775
+ "clientLinkId": "<clientLinkId>"
9776
+ }
9777
+ }
9778
+ ]
9779
+ },
9616
9780
  "bankRail/clientLinksList": {
9617
9781
  "name": "bankRail/clientLinksList",
9618
9782
  "method": "GET",
@@ -12877,8 +13041,8 @@
12877
13041
  "method": "GET",
12878
13042
  "url": "/api/v2/wallets/allocations/{allocationId}",
12879
13043
  "summary": "Read a wallet allocation",
12880
- "description": "Returns the durable allocation that creates a Canton party wallet. Use the allocation id from the 202 accept body. When status is awaiting-existing-approval, use lifecycleRequestId with the custody-account approval flow. An allocation of another organization answers the same not-found response as a missing allocation.",
12881
- "help": "Returns the durable allocation that creates a Canton party wallet. Use the allocation id from the 202 accept body. When status is awaiting-existing-approval, use lifecycleRequestId with the custody-account approval flow. An allocation of another organization answers the same not-found response as a missing allocation.",
13044
+ "description": "Returns the durable allocation that creates a Canton party wallet. Use the allocation id from the 202 accept body. When status is awaiting-existing-approval, use lifecycleRequestId with the custody-account approval flow. An allocation of another organization answers the same not-found response as a missing allocation. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13045
+ "help": "Returns the durable allocation that creates a Canton party wallet. Use the allocation id from the 202 accept body. When status is awaiting-existing-approval, use lifecycleRequestId with the custody-account approval flow. An allocation of another organization answers the same not-found response as a missing allocation. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
12882
13046
  "tags": [
12883
13047
  "Wallets"
12884
13048
  ],
@@ -12903,7 +13067,7 @@
12903
13067
  "bodyFields": [],
12904
13068
  "examples": [
12905
13069
  {
12906
- "description": "Returns the durable allocation that creates a Canton party wallet. Use the allocation id from the 202 accept body. When status is awaiting-existing-approval, use lifecycleRequestId with the custody-account approval flow. An allocation of another organization answers the same not-found response as a missing allocation.",
13070
+ "description": "Returns the durable allocation that creates a Canton party wallet. Use the allocation id from the 202 accept body. When status is awaiting-existing-approval, use lifecycleRequestId with the custody-account approval flow. An allocation of another organization answers the same not-found response as a missing allocation. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
12907
13071
  "path": {
12908
13072
  "allocationId": "<allocationId>"
12909
13073
  }
@@ -12915,8 +13079,8 @@
12915
13079
  "method": "POST",
12916
13080
  "url": "/api/v2/wallets",
12917
13081
  "summary": "Create a wallet",
12918
- "description": "Creates a custody-held wallet. Family canton allocates a Canton external party whose topology is signed automatically by the organization's custody-held Ed25519 key. A finished allocation returns 200. Background work and existing-signer approval return 202 with a status URL; the allocation status exposes the lifecycle request to approve.",
12919
- "help": "Creates a custody-held wallet. Family canton allocates a Canton external party whose topology is signed automatically by the organization's custody-held Ed25519 key. A finished allocation returns 200. Background work and existing-signer approval return 202 with a status URL; the allocation status exposes the lifecycle request to approve.",
13082
+ "description": "Creates a custody-held wallet. Family canton allocates a Canton external party whose topology is signed automatically by the organization's custody-held Ed25519 key. A finished allocation returns 200. Background work and existing-signer approval return 202 with a status URL; the allocation status exposes the lifecycle request to approve. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13083
+ "help": "Creates a custody-held wallet. Family canton allocates a Canton external party whose topology is signed automatically by the organization's custody-held Ed25519 key. A finished allocation returns 200. Background work and existing-signer approval return 202 with a status URL; the allocation status exposes the lifecycle request to approve. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
12920
13084
  "tags": [
12921
13085
  "Wallets"
12922
13086
  ],
@@ -12995,8 +13159,8 @@
12995
13159
  "method": "GET",
12996
13160
  "url": "/api/v2/wallets",
12997
13161
  "summary": "List wallets",
12998
- "description": "Returns one page of custody-held wallets for the selected participant in the active organization. Canton party wallets currently populate this list. Sort defaults to cantonPartyId ascending. Filter on family, party id, participant id, network id, or signer wallet id. Repeating the request is safe.",
12999
- "help": "Returns one page of custody-held wallets for the selected participant in the active organization. Canton party wallets currently populate this list. Sort defaults to cantonPartyId ascending. Filter on family, party id, participant id, network id, or signer wallet id. Repeating the request is safe.",
13162
+ "description": "Returns one page of custody-held wallets for the selected participant in the active organization. Canton party wallets currently populate this list. Sort defaults to cantonPartyId ascending. Filter on family, party id, participant id, network id, or signer wallet id. Repeating the request is safe. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13163
+ "help": "Returns one page of custody-held wallets for the selected participant in the active organization. Canton party wallets currently populate this list. Sort defaults to cantonPartyId ascending. Filter on family, party id, participant id, network id, or signer wallet id. Repeating the request is safe. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13000
13164
  "tags": [
13001
13165
  "Wallets"
13002
13166
  ],
@@ -13139,7 +13303,7 @@
13139
13303
  "bodyFields": [],
13140
13304
  "examples": [
13141
13305
  {
13142
- "description": "Returns one page of custody-held wallets for the selected participant in the active organization. Canton party wallets currently populate this list. Sort defaults to cantonPartyId ascending. Filter on family, party id, participant id, network id, or signer wallet id. Repeating the request is safe.",
13306
+ "description": "Returns one page of custody-held wallets for the selected participant in the active organization. Canton party wallets currently populate this list. Sort defaults to cantonPartyId ascending. Filter on family, party id, participant id, network id, or signer wallet id. Repeating the request is safe. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13143
13307
  "query": {
13144
13308
  "sort": "family"
13145
13309
  }
@@ -13151,8 +13315,8 @@
13151
13315
  "method": "GET",
13152
13316
  "url": "/api/v2/wallets/{walletId}",
13153
13317
  "summary": "Read a wallet",
13154
- "description": "Returns one custody-held wallet in the active organization. For a Canton party wallet the identifier is the external party id. A wallet that belongs to another organization answers the same not-found response as a missing wallet.",
13155
- "help": "Returns one custody-held wallet in the active organization. For a Canton party wallet the identifier is the external party id. A wallet that belongs to another organization answers the same not-found response as a missing wallet.",
13318
+ "description": "Returns one custody-held wallet in the active organization. For a Canton party wallet the identifier is the external party id. A wallet that belongs to another organization answers the same not-found response as a missing wallet. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13319
+ "help": "Returns one custody-held wallet in the active organization. For a Canton party wallet the identifier is the external party id. A wallet that belongs to another organization answers the same not-found response as a missing wallet. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13156
13320
  "tags": [
13157
13321
  "Wallets"
13158
13322
  ],
@@ -13177,7 +13341,7 @@
13177
13341
  "bodyFields": [],
13178
13342
  "examples": [
13179
13343
  {
13180
- "description": "Returns one custody-held wallet in the active organization. For a Canton party wallet the identifier is the external party id. A wallet that belongs to another organization answers the same not-found response as a missing wallet.",
13344
+ "description": "Returns one custody-held wallet in the active organization. For a Canton party wallet the identifier is the external party id. A wallet that belongs to another organization answers the same not-found response as a missing wallet. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13181
13345
  "path": {
13182
13346
  "walletId": "<walletId>"
13183
13347
  }
@@ -13189,8 +13353,8 @@
13189
13353
  "method": "POST",
13190
13354
  "url": "/api/v2/wallets/{walletId}/submissions",
13191
13355
  "summary": "Submit a DAML command (escape hatch)",
13192
- "description": "Submits a hand-built DAML command for a custody-held Canton party wallet through interactive submission. This is the escape hatch, not the ordinary write path: the caller supplies the template id, the choice name and the argument record itself, so a command that names them wrongly is refused by the ledger rather than by this platform. Reach for it only for a choice the platform does not yet model as a typed operation. For token issuance, burning, transfer, transfer acceptance and holding unlock, use the typed Canton token operations on the family-aware token collections under /api/v2/tokens/{assetId}, which state the operation in business terms and build the Daml themselves; for delivery-versus-payment use the XvP writes at /api/v2/addons/xvp-settlements, /api/v2/addons/xvp-settlements/{settlementAddress}/approvals and /api/v2/addons/xvp-settlements/{settlementAddress}/executions. When approval is required, the platform authorizes the command intent and re-prepares a fresh hash after approval. A settled command returns 200. When the platform accepts the work and finishes it in the background, the response is 202 with a status URL.",
13193
- "help": "Submits a hand-built DAML command for a custody-held Canton party wallet through interactive submission. This is the escape hatch, not the ordinary write path: the caller supplies the template id, the choice name and the argument record itself, so a command that names them wrongly is refused by the ledger rather than by this platform. Reach for it only for a choice the platform does not yet model as a typed operation. For token issuance, burning, transfer, transfer acceptance and holding unlock, use the typed Canton token operations on the family-aware token collections under /api/v2/tokens/{assetId}, which state the operation in business terms and build the Daml themselves; for delivery-versus-payment use the XvP writes at /api/v2/addons/xvp-settlements, /api/v2/addons/xvp-settlements/{settlementAddress}/approvals and /api/v2/addons/xvp-settlements/{settlementAddress}/executions. When approval is required, the platform authorizes the command intent and re-prepares a fresh hash after approval. A settled command returns 200. When the platform accepts the work and finishes it in the background, the response is 202 with a status URL.",
13356
+ "description": "Submits a hand-built DAML command for a custody-held Canton party wallet through interactive submission. This is the escape hatch, not the ordinary write path: the caller supplies the template id, the choice name and the argument record itself, so a command that names them wrongly is refused by the ledger rather than by this platform. Reach for it only for a choice the platform does not yet model as a typed operation. For token issuance, burning, transfer, transfer acceptance and holding unlock, use the typed Canton token operations on the family-aware token collections under /api/v2/tokens/{assetId}, which state the operation in business terms and build the Daml themselves; for delivery-versus-payment use the XvP writes at /api/v2/addons/xvp-settlements, /api/v2/addons/xvp-settlements/{settlementAddress}/approvals and /api/v2/addons/xvp-settlements/{settlementAddress}/executions. When approval is required, the platform authorizes the command intent and re-prepares a fresh hash after approval. A settled command returns 200. When the platform accepts the work and finishes it in the background, the response is 202 with a status URL. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13357
+ "help": "Submits a hand-built DAML command for a custody-held Canton party wallet through interactive submission. This is the escape hatch, not the ordinary write path: the caller supplies the template id, the choice name and the argument record itself, so a command that names them wrongly is refused by the ledger rather than by this platform. Reach for it only for a choice the platform does not yet model as a typed operation. For token issuance, burning, transfer, transfer acceptance and holding unlock, use the typed Canton token operations on the family-aware token collections under /api/v2/tokens/{assetId}, which state the operation in business terms and build the Daml themselves; for delivery-versus-payment use the XvP writes at /api/v2/addons/xvp-settlements, /api/v2/addons/xvp-settlements/{settlementAddress}/approvals and /api/v2/addons/xvp-settlements/{settlementAddress}/executions. When approval is required, the platform authorizes the command intent and re-prepares a fresh hash after approval. A settled command returns 200. When the platform accepts the work and finishes it in the background, the response is 202 with a status URL. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13194
13358
  "tags": [
13195
13359
  "Wallets"
13196
13360
  ],
@@ -13250,7 +13414,7 @@
13250
13414
  ],
13251
13415
  "examples": [
13252
13416
  {
13253
- "description": "Submits a hand-built DAML command for a custody-held Canton party wallet through interactive submission. This is the escape hatch, not the ordinary write path: the caller supplies the template id, the choice name and the argument record itself, so a command that names them wrongly is refused by the ledger rather than by this platform. Reach for it only for a choice the platform does not yet model as a typed operation. For token issuance, burning, transfer, transfer acceptance and holding unlock, use the typed Canton token operations on the family-aware token collections under /api/v2/tokens/{assetId}, which state the operation in business terms and build the Daml themselves; for delivery-versus-payment use the XvP writes at /api/v2/addons/xvp-settlements, /api/v2/addons/xvp-settlements/{settlementAddress}/approvals and /api/v2/addons/xvp-settlements/{settlementAddress}/executions. When approval is required, the platform authorizes the command intent and re-prepares a fresh hash after approval. A settled command returns 200. When the platform accepts the work and finishes it in the background, the response is 202 with a status URL.",
13417
+ "description": "Submits a hand-built DAML command for a custody-held Canton party wallet through interactive submission. This is the escape hatch, not the ordinary write path: the caller supplies the template id, the choice name and the argument record itself, so a command that names them wrongly is refused by the ledger rather than by this platform. Reach for it only for a choice the platform does not yet model as a typed operation. For token issuance, burning, transfer, transfer acceptance and holding unlock, use the typed Canton token operations on the family-aware token collections under /api/v2/tokens/{assetId}, which state the operation in business terms and build the Daml themselves; for delivery-versus-payment use the XvP writes at /api/v2/addons/xvp-settlements, /api/v2/addons/xvp-settlements/{settlementAddress}/approvals and /api/v2/addons/xvp-settlements/{settlementAddress}/executions. When approval is required, the platform authorizes the command intent and re-prepares a fresh hash after approval. A settled command returns 200. When the platform accepts the work and finishes it in the background, the response is 202 with a status URL. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13254
13418
  "path": {
13255
13419
  "walletId": "<walletId>"
13256
13420
  }
@@ -13262,8 +13426,8 @@
13262
13426
  "method": "POST",
13263
13427
  "url": "/api/v2/wallets/submissions/{submissionId}/decision",
13264
13428
  "summary": "Decide a DAML command intent",
13265
- "description": "Records an organization-owner or platform-administrator approval decision, then idempotently signals the durable Canton submission. Repeating the same decision is safe.",
13266
- "help": "Records an organization-owner or platform-administrator approval decision, then idempotently signals the durable Canton submission. Repeating the same decision is safe.",
13429
+ "description": "Records an organization-owner or platform-administrator approval decision, then idempotently signals the durable Canton submission. Repeating the same decision is safe. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13430
+ "help": "Records an organization-owner or platform-administrator approval decision, then idempotently signals the durable Canton submission. Repeating the same decision is safe. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13267
13431
  "tags": [
13268
13432
  "Wallets"
13269
13433
  ],
@@ -13318,7 +13482,7 @@
13318
13482
  ],
13319
13483
  "examples": [
13320
13484
  {
13321
- "description": "Records an organization-owner or platform-administrator approval decision, then idempotently signals the durable Canton submission. Repeating the same decision is safe.",
13485
+ "description": "Records an organization-owner or platform-administrator approval decision, then idempotently signals the durable Canton submission. Repeating the same decision is safe. Available only on a deployment that has `features.canton` switched on. While it is off, this route answers `404 ROUTE_NOT_FOUND`, the same answer as a route that does not exist.",
13322
13486
  "path": {
13323
13487
  "submissionId": "<submissionId>"
13324
13488
  }
@@ -56944,8 +57108,8 @@
56944
57108
  "method": "POST",
56945
57109
  "url": "/api/v2/tokens",
56946
57110
  "summary": "Create a token",
56947
- "description": "Deploys a new token for the active organization on the request chain, using a factory the organization can use. By default the platform queues the deployment and answers with the transaction identifier, its current state, and the status URL under status 202. A caller that sends Prefer: wait=<seconds> waits for settlement and receives the indexed token plus transaction hashes. Follow progress on the creation stream. A second identical call starts another deployment. The body may be the Canton instrument member instead: a member whose `type` is `canton` creates a Canton instrument, which the platform submits as one workflow of admin-single-party ledger commands and answers with the settled Canton arm under 201, or with the accepted shape when the work finishes in the background.",
56948
- "help": "Deploys a new token for the active organization on the request chain, using a factory the organization can use. By default the platform queues the deployment and answers with the transaction identifier, its current state, and the status URL under status 202. A caller that sends Prefer: wait=<seconds> waits for settlement and receives the indexed token plus transaction hashes. Follow progress on the creation stream. A second identical call starts another deployment. The body may be the Canton instrument member instead: a member whose `type` is `canton` creates a Canton instrument, which the platform submits as one workflow of admin-single-party ledger commands and answers with the settled Canton arm under 201, or with the accepted shape when the work finishes in the background.",
57111
+ "description": "Deploys a new token for the active organization on the request chain, using a factory the organization can use. By default the platform queues the deployment and answers with the transaction identifier, its current state, and the status URL under status 202. A caller that sends Prefer: wait=<seconds> waits for settlement and receives the indexed token plus transaction hashes. Follow progress on the creation stream. A second identical call starts another deployment. The body may be the Canton instrument member instead: a member whose `type` is `canton` creates a Canton instrument, which the platform submits as one workflow of admin-single-party ledger commands and answers with the settled Canton arm under 201, or with the accepted shape when the work finishes in the background. `templateId` is required for `dalp-asset` and optional for a classic asset type. The platform creates a classic type only when its operator turned on legacy asset creation, and otherwise refuses it with HTTP 422 and `TOKEN_CREATE_ASSET_FAMILY_DEPRECATED`. A classic type created without a template gets no template checks; with one, it gets only the check that the template is published and not hidden from Issue asset, and is refused with `TemplateFeaturesUnavailable` when the template declares features.",
57112
+ "help": "Deploys a new token for the active organization on the request chain, using a factory the organization can use. By default the platform queues the deployment and answers with the transaction identifier, its current state, and the status URL under status 202. A caller that sends Prefer: wait=<seconds> waits for settlement and receives the indexed token plus transaction hashes. Follow progress on the creation stream. A second identical call starts another deployment. The body may be the Canton instrument member instead: a member whose `type` is `canton` creates a Canton instrument, which the platform submits as one workflow of admin-single-party ledger commands and answers with the settled Canton arm under 201, or with the accepted shape when the work finishes in the background. `templateId` is required for `dalp-asset` and optional for a classic asset type. The platform creates a classic type only when its operator turned on legacy asset creation, and otherwise refuses it with HTTP 422 and `TOKEN_CREATE_ASSET_FAMILY_DEPRECATED`. A classic type created without a template gets no template checks; with one, it gets only the check that the template is published and not hidden from Issue asset, and is refused with `TemplateFeaturesUnavailable` when the template declares features.",
56949
57113
  "tags": [
56950
57114
  "Token creation"
56951
57115
  ],
package/src/lib/errors.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import { findDalpSdkError, isDalpApiError } from "@settlemint/dalp-sdk";
2
2
  import { buildErrorCta, extractResourceLinks, type CliCtaBlock, type ResourceLinks } from "./cli-cta.ts";
3
+ import type { GatedFeature } from "./feature-gated-operations.ts";
3
4
 
4
5
  export interface CliErrorContext {
5
6
  readonly code: string;
6
7
  readonly fallbackMessage: string;
7
8
  readonly fallbackWhy: string;
8
9
  readonly fallbackFix: string;
10
+ readonly gatedFeature?: GatedFeature;
9
11
  }
10
12
 
11
13
  export interface RenderedCliError {
@@ -171,8 +173,25 @@ function normalizeFailure(error: unknown, context: CliErrorContext): NormalizedF
171
173
  };
172
174
  }
173
175
 
176
+ const ROUTE_NOT_FOUND_CODE = "ROUTE_NOT_FOUND";
177
+
178
+ function featureNotEnabledFailure(feature: GatedFeature): NormalizedFailure {
179
+ return {
180
+ code: "FEATURE_NOT_ENABLED",
181
+ message: `${feature.name} is not enabled on this deployment.`,
182
+ why: `The platform answered with an unknown route because ${feature.name} is switched off (${feature.setting}), so it does not serve this command.`,
183
+ fix: `Ask the operator of this deployment to switch ${feature.name} on, or use a deployment that has it enabled.`,
184
+ retryable: false,
185
+ category: "domain",
186
+ };
187
+ }
188
+
174
189
  export function renderSdkErrorForCli(error: unknown, context: CliErrorContext): RenderedCliError {
175
- const failure = normalizeFailure(error, context);
190
+ const normalized = normalizeFailure(error, context);
191
+ const failure =
192
+ context.gatedFeature !== undefined && normalized.code === ROUTE_NOT_FOUND_CODE
193
+ ? featureNotEnabledFailure(context.gatedFeature)
194
+ : normalized;
176
195
  return {
177
196
  code: failure.code,
178
197
  message: failure.message,
@@ -0,0 +1,18 @@
1
+ export interface GatedFeature {
2
+ readonly name: string;
3
+ readonly setting: string;
4
+ }
5
+
6
+ const FEATURE_GATED_OPERATION_GROUPS: Readonly<Record<string, GatedFeature>> = {
7
+ cantonV2: { name: "Canton", setting: "features.canton" },
8
+ };
9
+
10
+ export const gatedFeatureOfOperation = (operationName: string): GatedFeature | undefined => {
11
+ const group = operationName.split(".", 1)[0] ?? "";
12
+ return Object.hasOwn(FEATURE_GATED_OPERATION_GROUPS, group) ? FEATURE_GATED_OPERATION_GROUPS[group] : undefined;
13
+ };
14
+
15
+ export const gatedFeatureContext = (operationName: string): { readonly gatedFeature?: GatedFeature } => {
16
+ const gatedFeature = gatedFeatureOfOperation(operationName);
17
+ return gatedFeature === undefined ? {} : { gatedFeature };
18
+ };
@@ -3,6 +3,7 @@ import { Cli, z } from "incur";
3
3
  import { buildErrorCta, buildSuccessCtaFromResult, renderCtaText, type CliCtaBlock } from "./cli-cta.ts";
4
4
  import { createCliStatus } from "./cli-status.ts";
5
5
  import { renderSdkErrorForCli } from "./errors.ts";
6
+ import { gatedFeatureContext } from "./feature-gated-operations.ts";
6
7
  import { INDEX_COMMAND } from "@settlemint/dalp-sdk/routes";
7
8
  import { listCliOperations, operationHintKey, type OperationDescriptor } from "./operation-inventory.ts";
8
9
  import { tagDescription, type SurfaceOperation } from "./openapi-surface.ts";
@@ -447,6 +448,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
447
448
  fallbackMessage: "Operation failed.",
448
449
  fallbackWhy: "The DALP API rejected the request or the network call failed.",
449
450
  fallbackFix: "Verify authentication, organization context, and args/options, then retry.",
451
+ ...gatedFeatureContext(descriptor.name),
450
452
  }
451
453
  );
452
454
 
@@ -480,6 +482,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
480
482
  fallbackMessage: "SSE stream failed",
481
483
  fallbackWhy: "The Server-Sent Events stream ended with an error before a terminal event.",
482
484
  fallbackFix: "Retry the stream command, or poll the matching status endpoint.",
485
+ ...gatedFeatureContext(descriptor.name),
483
486
  });
484
487
  const failed = status.fail(rendered.message);
485
488
  if (failed !== undefined) {