/**
 * # Token Update
 * Modify the characteristics of an existing token. Most changes require that
 * the transaction be signed by an `admin_key`, and if that key is not valid
 * the only change permitted is to extend the token expiration.
 *
 * ### Keywords
 * The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
 * "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
 * document are to be interpreted as described in
 * [RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in
 * [RFC8174](https://www.ietf.org/rfc/rfc8174).
 */
syntax = "proto3";

package proto;

// SPDX-License-Identifier: Apache-2.0
option java_package = "com.hederahashgraph.api.proto.java";
// <<<pbj.java_package = "com.hedera.hapi.node.token">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;

import "services_basic_types.proto";
import "services_duration.proto";
import "services_timestamp.proto";
import "google/protobuf/wrappers.proto";

/**
 * Update an existing token.
 *
 * This transaction SHALL NOT update any field that is not set.<br/>
 * Most changes MUST be signed by the current `admin_key` of the token. If the
 * token does not currently have a valid `admin_key`, then this transaction
 * MUST NOT set any value other than `expiry` or a non-admin key.<br/>
 * If the `treasury` is set to a new account, the new account MUST sign this
 * transaction.<br/>
 * If the `treasury` is set to a new account for a _non-fungible/unique_ token,
 * The current treasury MAY hold some tokens.
 *
 * #### Requirements for Keys
 * Any of the key values may be changed, even without an admin key, but the
 * key to be changed MUST have an existing valid key assigned, and both the
 * current key and the new key MUST sign the transaction.<br/>
 * A key value MAY be set to an empty `KeyList`. In this case the existing
 * key MUST sign this transaction, but the new value is not a valid key, and the
 * update SHALL effectively remove the existing key.
 *
 * ### Block Stream Effects
 * None
 */
message TokenUpdateTransactionBody {
    /**
     * A token identifier.
     * <p>
     * This SHALL identify the token type to delete.<br/>
     * The identified token MUST exist, and MUST NOT be deleted.<br/>
     * If any field other than `expiry` is set, the identified token MUST
     * have a valid `admin_key`.
     */
    TokenID token = 1;

    /**
     * A new symbol to use for the token.
     * <p>
     * This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.<br/>
     * This value, if set, MUST NOT contain the Unicode NUL codepoint.
     */
    string symbol = 2;

    /**
     * A new name for the token.<br/>
     * This is generally the "full name" displayed in wallet software.
     * <p>
     * This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.<br/>
     * This value, if set, MUST NOT contain the Unicode NUL codepoint.
     */
    string name = 3;

    /**
     * A new treasury account identifier.
     * <p>
     * If set,
     * - The identified account SHALL be designated the "treasury" for the
     *   token, and all tokens "minted" SHALL be delivered to that account
     *   following this transaction.<br/>
     * - The identified account MUST exist, MUST NOT be expired, MUST NOT be
     *   deleted, and SHOULD have a non-zero HBAR balance.<br/>
     * - The identified account SHALL be associated to this token.
     * - The full balance of this token held by the prior treasury account
     *   SHALL be transferred to the new treasury account, if the token type
     *   is fungible/common.
     * - If the token type is non-fungible/unique, the previous treasury
     *   account MUST NOT hold any tokens of this type.
     * - The new treasury account key MUST sign this transaction.
     */
    AccountID treasury = 4;

    /**
     * An Hedera key for token administration.
     * <p>
     * This key, if set, SHALL have administrative authority for this token and
     * MAY authorize token update and/or token delete transactions.<br/>
     * If this key is set to an empty `KeyList`, this token SHALL be
     * immutable thereafter, except for expiration and renewal.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key adminKey = 5;

    /**
     * An Hedera key for managing account KYC.
     * <p>
     * This key, if set, SHALL have KYC authority for this token and
     * MAY authorize transactions to grant or revoke KYC for accounts.<br/>
     * If this key is not set, or is an empty `KeyList`, KYC status for this
     * token SHALL NOT be granted or revoked for any account.<br/>
     * If this key is removed after granting KYC, those grants SHALL remain
     * and cannot be revoked.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key kycKey = 6;

    /**
     * An Hedera key for managing asset "freeze".
     * <p>
     * This key, if set, SHALL have "freeze" authority for this token and
     * MAY authorize transactions to freeze or unfreeze accounts
     * with respect to this token.<br/>
     * If this key is set to an empty `KeyList`, this token
     * SHALL NOT be frozen or unfrozen for any account.<br/>
     * If this key is removed after freezing accounts, those accounts
     * SHALL remain frozen and cannot be unfrozen.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key freezeKey = 7;

    /**
     * An Hedera key for wiping tokens from accounts.
     * <p>
     * This key, if set, SHALL have "wipe" authority for this token and
     * MAY authorize transactions to "wipe" any amount of this token from
     * any account, effectively burning the tokens "wiped".<br/>
     * If this key is set to an empty `KeyList`, it SHALL NOT be
     * possible to "wipe" this token from an account.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key wipeKey = 8;

    /**
     * An Hedera key for "minting" and "burning" tokens.
     * <p>
     * This key, if set, MAY authorize transactions to "mint" new tokens to
     * be delivered to the token treasury or "burn" tokens held by the
     * token treasury.<br/>
     * If this key is set to an empty `KeyList`, it SHALL NOT be
     * possible to change the supply of tokens and neither "mint" nor "burn"
     * transactions SHALL be permitted.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key supplyKey = 9;

    /**
     * An identifier for the account to be charged renewal fees at the token's
     * expiry to extend the lifetime of the token.
     * <p>
     * If this value is set for the identified token, the token lifetime SHALL
     * be extended by the _smallest_ of the following at expiration:
     * <ul>
     *   <li>The current `autoRenewPeriod` duration.</li>
     *   <li>The maximum duration that this account has funds to purchase.</li>
     *   <li>The configured MAX_AUTORENEW_PERIOD at the time of automatic
     *       renewal.</li>
     * </ul>
     * If this account's HBAR balance is `0` when the token must be
     * renewed, then the token SHALL be expired, and MAY be subsequently
     * removed from state.<br/>
     * If this value is set, the referenced account MUST sign this
     * transaction.
     * <p>
     * <blockquote>Note<blockquote>
     * It is not currently possible to remove an automatic renewal account.
     * Once set, it can only be replaced by a valid account.
     * </blockquote></blockquote>
     */
    AccountID autoRenewAccount = 10;

    /**
     * A duration between token automatic renewals.<br/>
     * All entities in state may be charged "rent" occasionally (typically
     * every 90 days) to prevent unnecessary growth of the ledger. This value
     * sets the interval between such events for this token.
     * <p>
     * If set, this value MUST be greater than the configured
     * `MIN_AUTORENEW_PERIOD`.<br/>
     * If set, this value MUST be less than the configured
     * `MAX_AUTORENEW_PERIOD`.
     */
    Duration autoRenewPeriod = 11;

    /**
     * An expiration timestamp.
     * <p>
     * If this value is set, the automatic renewal account is not set for the
     * identified token, and token expiration is enabled in network
     * configuration, this token SHALL expire when the consensus time exceeds
     * this value, and MAY be subsequently removed from the network state.<br/>
     * If `autoRenewAccount` is set or the `auto_renew_account_id` is set for
     * the identified token, the token SHALL be subject to automatic renewal
     * when the consensus time exceeds this value.
     */
    Timestamp expiry = 12;

    /**
     * A short description for this token.
     * <p>
     * This value, if set, MUST NOT exceed `transaction.maxMemoUtf8Bytes`
     * (default 100) bytes when encoded as UTF-8.
     */
    google.protobuf.StringValue memo = 13;

    /**
     * An Hedera key for managing the token custom fee schedule.
     * <p>
     * This key, if set, MAY authorize transactions to modify the
     * `custom_fees` for this token.<br/>
     * If this key is set to an empty `KeyList`, the `custom_fees`
     * for this token SHALL NOT be modified.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key fee_schedule_key = 14;

    /**
     * An Hedera key for managing token "pause".
     * <p>
     * This key, if set, SHALL have "pause" authority for this token and
     * MAY authorize transactions to pause or unpause this token.<br/>
     * If this key is set to an empty `KeyList`, this token
     * SHALL NOT be paused or unpaused.<br/>
     * If this key is removed while the token is paused, the token cannot
     * be unpaused and SHALL remain paused.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key pause_key = 15;

    /**
     * Token "Metadata".
     * <p>
     * The value, if set, MUST NOT exceed 100 bytes.<br/>
     * <dl><dt>Examples</dt>
     *   <dd>hcs://1/0.0.4896575</dd>
     *   <dd>ipfs://bafkreifd7tcjjuwxxf4qkaibkj62pj4mhfuud7plwrc3pfoygt55al6syi</dd>
     * </dl>
     */
    google.protobuf.BytesValue metadata = 16;

    /**
     * An Hedera key for managing the token `metadata`.
     * <p>
     * This key, if set, MAY authorize transactions to modify the
     * `metadata` for this token.<br/>
     * If this key is set to an empty `KeyList`, the `metadata`
     * for this token SHALL NOT be modified.<br/>
     * If set, this key MUST be a valid key or an empty `KeyList`.<br/>
     * If set to a valid key, the previous key and new key MUST both
     * sign this transaction.
     */
    Key metadata_key = 17;

    /**
     * Set a key validation mode.<br/>
     * Any key may be updated by a transaction signed by the token `admin_key`.
     * Each role key may _also_ sign a transaction to update that key.
     * If a role key signs an update to change that role key both old
     * and new key must sign the transaction, _unless_ this field is set
     * to `NO_VALIDATION`, in which case the _new_ key is not required to
     * sign the transaction (the existing key is still required).<br/>
     * The primary intent for this field is to allow a role key (e.g. a
     * `pause_key`) holder to "remove" that key from the token by signing
     * a transaction to set that role key to an empty `KeyList`.
     * <p>
     * If set to `FULL_VALIDATION`, either the `admin_key` or _both_ current
     * and new key MUST sign this transaction to update a "key" field for the
     * identified token.<br/>
     * If set to `NO_VALIDATION`, either the `admin_key` or the current
     * key MUST sign this transaction to update a "key" field for the
     * identified token.<br/>
     * This field SHALL be treated as `FULL_VALIDATION` if not set.
     */
    TokenKeyValidation key_verification_mode = 18;
}
