Skip to main content

Flags

Flags control access to an asset and are set by an issuing account using the set_options operation. Flags can be set at any time (unless the Authorization Immutable flag is set), but do not apply to existing trustlines.

Flag types

The (0xn) next to each flag type denotes the bit settings for each flag.

Authorization Required (0x1)

When AUTHORIZATION REQUIRED is enabled, an issuer must approve an account before that account can hold its asset. This setting allows issuers to vet potential token holders and to approve trustlines.

To allow access, the user creates a trustline, and the issuer approves it by changing the AUTHORIZE flag with the Set_Trust_Line_Flag operation.

There are two levels of authorization an asset issuer can grant using the Set_Trust_Line_Flag operation:

  • AUTHORIZED: signifies complete authorization allowing an account to transact freely with the asset to make and receive payments and place orders.
  • AUTHORIZED_TO_MAINTAIN_LIABILITIES: denotes limited authorization that allows an account to maintain current orders but not to otherwise transact with the asset.

Authorization Revocable (0x2)

When AUTHORIZATION_REVOCABLE is enabled, an issuer can revoke an existing trustline’s authorization, thereby freezing the asset held by an account. Doing so prevents that account from transferring or trading the asset and cancels the account’s open orders for the asset.

AUTHORIZATION_REVOCABLE also allows an issuer to reduce authorization from complete to limited, which prevents the account from transferring or trading the asset but does not cancel the account’s open orders for the asset. This setting is useful for issuers of regulated assets who need to authorize transactions on a case-by-case basis to ensure each conforms to certain requirements.

All changes to asset authorization are performed with the Set Trustline Flags operation.

There are three levels of authorization an asset issuer can remove using the Set_Trust_Line_Flag operation:

  • AUTHORIZED: signifies complete authorization allowing an account to transact freely with the asset to make and receive payments and place orders.
  • AUTHORIZED_TO_MAINTAIN_LIABILITIES: denotes limited authorization that allows an account to maintain current orders but not to otherwise transact with the asset.
  • CLAWBACK_ENABLED: enables the issuing account to take back (burning) all of the asset. See our section on Clawbacks for more information.

Clawback Enabled (0x8)

With the AUTHORIZATION_CLAWBACK_ENABLED flag set, any subsequent trustlines established with this account will have clawbacks enabled.

Read more about clawbacks in the Clawback Encyclopedia Entry.

Note that this flag requires that revocable is also set.

Authorization Immutable (0x4)

With this setting, none of the other authorization flags (AUTHORIZATION REQUIRED, AUTHORIZATION REVOCABLE) can be set, and the issuing account can’t be merged. You set this flag to signal to potential token holders that your issuing account and its assets will persist on the ledger in an open and accessible state.

Set Trustline Flag operation

The issuing account can configure various authorization and trustline flags for individual trustlines to an asset.

The Asset parameter is of the TrustLineAsset type. If you are modifying a trustline to a regular asset (i.e. one in a Code:Issuer format), this is equivalent to the Asset type. If you are modifying a trustline to a pool share, this is the liquidity pool’s unique ID.

Example flow

Let’s look at how an issuer of a regulated asset might use the AUTHORIZED_TO_MAINTAIN_LIABILITIES flag.

If the issuer wants to approve transactions on a case-by-case basis while allowing accounts to maintain offers, they can leave an account in the AUTHORIZED_TO_MAINTAIN_LIABILITIES state. That account can own offers but cannot do anything else with the asset.

To initiate a new operation, the holding account requests that the issuer approve and sign a transaction. Once the issuer inspects the operation and decides to approve it, they sandwich it between a set of operations, first granting authorization, then reducing it.

Here’s a payment from A to B sandwiched between set_trust_line_flags operations:

  • Operation 1: Issuer uses SetTrustLineFlags to fully authorize account A, asset X
  • Operation 2: Issuer uses SetTrustLineFlags to fully authorize account B, asset X
  • Operation 3: Payment from A to B
  • Operation 4: Issuer uses SetTrustLineFlags to set account B, asset X to AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG state
  • Operation 5: Issuer uses SetTrustLineFlags to set account A, asset X to AUTHORIZED_TO_MAINTAIN_LIABILITIES_FLAG state

The authorization sandwich allows the issuer to inspect the specific payment and to grant authorization for it and it alone. Since operations bundled in a transaction are simultaneous, A and B are only authorized for the specific, pre-approved payment operation. Complete authorization does not extend beyond the specific transaction.

Sample code

In the following code samples, proper error checking is omitted. However, you should always validate your results, as there are many ways that requests can fail. Refer to the Error Handling Encyclopedia Entry for tips on error management strategies.

The following example sets authorization to be both required and revocable:

var StellarSdk = require("stellar-sdk");var server = new StellarSdk.Server("https://horizon-testnet.stellar.org");// Keys for issuing accountvar issuingKeys = StellarSdk.Keypair.fromSecret(  "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4",);server  .loadAccount(issuingKeys.publicKey())  .then(function (issuer) {    var transaction = new StellarSdk.TransactionBuilder(issuer, {      fee: 100,      networkPassphrase: StellarSdk.Networks.TESTNET,    })      .addOperation(        StellarSdk.Operation.setOptions({          setFlags: StellarSdk.AuthRevocableFlag | StellarSdk.AuthRequiredFlag,        }),      )      // setTimeout is required for a transaction      .setTimeout(100)      .build();    transaction.sign(issuingKeys);    return server.submitTransaction(transaction);  })  .then(console.log)  .catch(function (error) {    console.error("Error!", error);  });