Skip to content
Last updated

🟩 Request to Hold a Tokenized Asset in a Given Wallet

This is the process of white-listing a token for a given wallet, basically saying: the owner of wallet 0xyz has been verified and is allowed to receive the digital security. This process is also called an opt-in.

Prerequisites:

Before requesting an asset opt-in:

  • The token must be created in the NYALA system (this can be done in our Web Portal or via API, and it is not necessary that the token is finalized on-chain yet)
  • You must have the token internal ID (traceID in NYALA)
  • The customer must have an existing crypto wallet with the custodian, or a wallet creation request must be initiated; External wallets must be imported into the NYALA system

Manually Create Project and Token

If you do not wish to create projects and tokens via API, you can easily do so manually in our web portal. These steps can be achieved via the NYALA Web Portal to which you will receive access at the beginning of your onboarding.

ℹ️ If you prefer to trigger these operations via API, then go to the full integration chapter.

1) Request asset opt-in

Send an opt-in request using the appropriate endpoint based on your wallet type:

  • POST Asset class opt-in for wallets custodied by Tangany /api/external/v1/customers/{customerId}/asset-class-opt-in

  • POST External opt-in for external wallets /api/external/v1/customers/{customerId}/retail-wallets/{external_wallet_id}//external-asset-class-opt-in

Request Example:

# UAT BASE_URL: https://uat.api.nyala.de
# Production BASE_URL: https://api.nyala.de

# The {customerId} is 42557ea2-8a55-4599-85b2-2a91f343a08b

curl -X POST {{BASE_URL}}/api/external/v1/customers/42557ea2-8a55-4599-85b2-2a91f343a08b/asset-class-opt-in \
-H "Content-Type: application/json" \
-H "Authorization: HMAC YOUR_API_KEY:GENERATED_SIGNATURE" \
-H "Content-Length: CALCULATED_CONTENT_LENGTH" \
-d '{
  "tokenizedAssetId": "{tokenized_asset_id}",
  "amount": 10,
  "approvedForDelivery": true,
  "custodyProvider": 1
}'
# UAT BASE_URL: https://uat.api.nyala.de
# Production BASE_URL: https://api.nyala.de

# The {customerId} is 42557ea2-8a55-4599-85b2-2a91f343a08b
# The {external-wallet-id} is 5ce576ef-ef6d-4d5b-b165-511e2a72fe7c

curl -X POST {{BASE_URL}}/api/external/v1/customers/42557ea2-8a55-4599-85b2-2a91f343a08b/retail-wallets/5ce576ef-ef6d-4d5b-b165-511e2a72fe7c/external-asset-class-opt-in \
-H "Content-Type: application/json" \
-H "Authorization: HMAC YOUR_API_KEY:GENERATED_SIGNATURE" \
-H "Content-Length: CALCULATED_CONTENT_LENGTH" \
-d '{
  "tokenizedAssetId": "{tokenized_asset_id}",
  "approvedForDelivery": true,
  "amount": 10
}'
Parameter Name
Description
Expected Values
tokenizedAssetIdThe token Internal ID (traceID in NYALA) that specifies which asset you want to allocate.UUID of the tokenized asset
amountThe token quantity in units to allocate to the wallet (the investor)."100", "500", "1000", etc.
approvedForDeliveryOptional. Indicates whether the wallet is eligible to receive tokens.
If true: The wallet will receive tokens when you trigger automatic distribution (see "Send tokens in one batch").
If false: The wallet will not receive tokens during automatic distribution
"True", "False"
txHashOptional. Only relevant for external wallets on the Stellar blockchain. Use this to send a message confirming that the transaction has been signed by the Stellar wallet. You can then check for the AuthOptIn (7) transaction to confirm that the opt-in has been granted"Trustline created"

ℹ️ A note on revoking opt-ins: You cannot directly revoke the opt-in for an investor, as it revokes the opt-in for the whole AssetClass (meaning they would for example not be allowed to hold any bond tokens or share tokens from your institution anymore). If you just want to ensure that an investor, for which you have previously sent an opt-in, cannot hold a specific token anymore, you can change the amount of opt-in to 0 and set ApprovedForDelivery = False.

Response Example:

{
  "errorMessageCodes": null,
  "errors": null,
  "data": "6435a3c3-5778-4578-bd2a-9394a10b15b0"
}

Bad Request - 400

{
    "errorMessageCodes": [
        "ColistingOptInOversubscription"
    ],
    "errors": [
        {
            "code": "ColistingOptInOversubscription",
            "message": "Oversubscription. The total opt-in amount is higher than your
                allocated token amount. Adjust existing opt-in amounts if need be.",
            "field": null
        }
    ],
    "data": "00000000-0000-0000-0000-000000000000",
    "warnings": null
}

Example Use Case

Set approved_for_delivery to false when an investor initially places an order during the subscription period. After the investment is confirmed and the withdrawal period ends, update the value to true to enable token delivery.

2) Update asset opt-in

You can update an existing opt-in request using PATCH Asset class opt-in. Use this endpoint to modify the token amount and/or approved for delivery status. Not releavant for External OptIns

PATCH Asset class opt-in /api/external/v1/customers/{customerId}/asset-class-opt-in

Request Example:

# UAT BASE_URL: https://uat.api.nyala.de
# Production BASE_URL: https://api.nyala.de

# The {customerId} is 42557ea2-8a55-4599-85b2-2a91f343a08b

curl -X PATCH {{BASE_URL}}/api/external/v1/customers/42557ea2-8a55-4599-85b2-2a91f343a08b/asset-class-opt-in \
-H "Content-Type: application/json" \
-H "Authorization: HMAC YOUR_API_KEY:GENERATED_SIGNATURE" \
-H "Content-Length: CALCULATED_CONTENT_LENGTH" \
-d '{
  "tokenizedAssetId": "{tokenized_asset_id}",
  "amount": 20,
  "approvedForDelivery": true,
  "custodyProvider": 1
}'

Response Example:

{
    "errorMessageCodes": null,
    "errors": null,
    "data": true
}

Bad Request - 400

{
    "errorMessageCodes": [
        "ColistingOptInOversubscription"
    ],
    "errors": [
        {
            "code": "ColistingOptInOversubscription",
            "message": "Oversubscription. The total opt-in amount is higher than your
                allocated token amount. Adjust existing opt-in amounts if need be.",
            "field": null
        }
    ],
    "data": "00000000-0000-0000-0000-000000000000",
    "warnings": null
}

ℹ️ To update external wallets opt-ins: you can re-use the same endpoint as for creating said opt-in in the first place. You can only edit the token amount and the status of ApprovedForDelivery. Use POST: /api/external/v1/customers/{customerId}/retail-wallets/{external_wallet_id}//external-asset-class-opt-in

Errors

CaseError codeExample response
Customer or Tokenized Asset not found404"errorMessageCodes": ["CustomerNotFound"]
Customer has no wallet associated with them404"errorMessageCodes": ["CustomerHasNoWallets"]
Token ID does not belong to the institution and no co-listing request was created404"errorMessageCodes": ["TokenizedAssetColistingPartnersNotFoundOrInvalidStatus"]
Only applicable to co-listed tokens: Status of the co-listing is 'cancelled' or 'delisted', so the Co-Lister cannot send an opt-in for this project404"errorMessageCodes: ["ColistingCancelledOrDelisted"]
Only applicable to co-listed tokens: the co-listing project cannot be found, so no opt-in can be sent for this project404"errorMessageCodes": ["TokenizedAssetColistingPartnersNotFoundOrInvalidStatus"]
Only applicable to co-listed tokens: The status of the co-listing project is not in progress (i.e. it is draft, the project does not accept more investors, or it was cancelled)404"errorMessageCodes": ["TokenizedAssetColistingPartnersNotFoundOrInvalidStatus"]
Only applicable to co-listed tokens: The customer raised some flags at liability umbrella Concedus and was not approved404See the possible Concedus status codes "errorMessageCodes": ["CustomerConcedusCompliantStatusInvalid"]
Only applicable to co-listed tokens: The requested optin's amount and the already accepted optin sum is higher than the allocated token amount for colister.400"errorMessageCodes": ["ColistingOptInOversubscription"]