Blockstream Enterprise Custody SDK
Issuer Guide (SDK)

Restriction management

Restrictions control asset destinations and burn permissions. The page explains restriction concepts, queries, updates, enforcement, and operational guidance.

Restrictions control where an asset can be sent and whether it can be burned. They are the primary compliance tool in AMP2.

Restriction concepts

FieldMeaning
widsWallets this restriction group applies to
toWhitelistAllowed destination wallets for transfers
useToWhitelistIf true, only whitelist destinations allowed
canBurnIf true, wallets in this group can burn the asset

Restrictions are enforced by the HSM at PSET cosigning time. If a transfer or burn violates the active policy, AMP2 refuses to cosign.

Create a single wallet restriction

Apply a restriction to one wallet for one asset:

import {
  EditAssetWalletRestrictionRequestSchema,
  type AmpActions,
} from '@blockstream/amp-registry';

const restrictionResult = await broadcastRequest<
  typeof AmpActions.editAssetWalletRestrictions
>({
  action: 'edit',
  resource: `/amp/assets/${assetId}/wallets/${walletId}/restrictions`,
  details: {
    can_burn: false,
    whitelist: [treasuryWid, approvedInvestorWid],
  },
}, broadcaster);

if (restrictionResult.status !== 'success') {
  throw new Error(`Failed to set restriction: ${restrictionResult.message}`);
}

This means: when walletId holds this asset, it can only send to treasuryWid or approvedInvestorWid. It cannot burn.

Create bulk restrictions

Apply the same policy to multiple wallets:

import type { AmpActions } from '@blockstream/amp-registry';

const bulkRestrictionResult = await broadcastRequest<
  typeof AmpActions.editAssetWalletRestrictionsList
>({
  action: 'edit',
  resource: `/amp/assets/${assetId}/restrictions`,
  details: {
    can_burn: false,
    use_to_whitelist: true,
    to_whitelist: [treasuryWid, approvedWid1, approvedWid2],
    wids: [investorWid1, investorWid2, investorWid3],
  },
}, broadcaster);

All three investor wallets now share the same restriction group with the same whitelist and burn permissions.

Query restrictions

V1 format

const restrictions = await broadcastRequest<
  typeof AmpActions.getAssetRestrictions
>({
  action: 'get',
  resource: `/amp/assets/${assetId}/restrictions`,
}, broadcaster);

V2 format (expanded group details)

const restrictionsV2 = await broadcastRequest<
  typeof AmpActions.getAssetRestrictionsV2
>({
  action: 'get',
  resource: `/amp/assets/v2/${assetId}/restrictions`,
}, broadcaster);

if (restrictionsV2.status !== 'success') {
  throw new Error('Failed to get asset restrictions');
}

The V2 response includes expanded group membership details.

Per wallet restriction

const walletRestriction = await broadcastRequest<
  typeof AmpActions.getAssetWalletRestrictions
>({
  action: 'get',
  resource: `/amp/assets/${assetId}/wallets/${walletId}/restrictions`,
}, broadcaster);

Delete restrictions

Delete a wallet's restriction

await broadcastRequest<
  typeof AmpActions.deleteAssetWalletRestrictions
>({
  action: 'delete',
  resource: `/amp/assets/${assetId}/wallets/${walletId}/restrictions`,
}, broadcaster);

Delete an entire restriction group

await broadcastRequest<
  typeof AmpActions.deleteAssetWalletRestrictionByGroup
>({
  action: 'delete',
  resource: `/amp/assets/${assetId}/restrictions/group/${groupId}`,
}, broadcaster);

Updating restrictions

There is no in place update operation. To change a wallet's restriction policy:

  1. Delete the existing restriction (by wallet or by group).
  2. Create a new restriction with the updated policy.

Enforcement and transfer relationship

When an issuer calls the send endpoint:

  1. AMP2 constructs the PSET with the requested recipients.
  2. The HSM checks the source wallet's restriction group for this asset.
  3. If useToWhitelist is true, every recipient must be in the toWhitelist.
  4. If the transaction burns tokens, canBurn must be true for the source wallet.
  5. If any check fails, the cosign request is refused.

Operational guidance

  • Always include the treasury wallet in whitelists: investors typically need to be able to return assets to the issuer.
  • Keep whitelist updates atomic: delete and recreate in a single operation flow to avoid a window where the policy is misconfigured.
  • Log all restriction changes: record operator, timestamp, reason, and the old/new policy in your issuer systems.
  • Test on testnet: restriction enforcement is strict. A misconfigured whitelist will block legitimate transfers with no override.

Next steps

On this page