CCC Docs
    Preparing search index...

    Represents a User Defined Token (UDT) script compliant with the SSRI protocol.

    This class provides a comprehensive implementation for interacting with User Defined Tokens, supporting various token operations such as querying metadata, checking balances, and performing transfers. It supports both SSRI-compliant UDTs and legacy sUDT/xUDT standard tokens.

    Hierarchy (View Summary)

    Index

    Constructors

    • Constructs a new UDT (User Defined Token) script instance. By default it is a SSRI-compliant UDT. This class supports both SSRI-compliant UDTs and legacy sUDT/xUDT standard tokens.

      Parameters

      • code: OutPointLike

        The script code cell outpoint of the UDT. This points to the cell containing the UDT script code

      • script: ScriptLike

        The type script of the UDT that uniquely identifies this token

      • Optionalconfig: null | UdtConfigLike

        Optional configuration object for advanced settings

        • null
        • UdtConfigLike

          Configuration object type for UDT instances. This type defines the optional configuration parameters that can be passed when creating a UDT instance to customize its behavior.

          • Optionalexecutor?: Executor | null

            Optional SSRI executor instance for advanced UDT operations. When provided, enables SSRI-compliant features like metadata queries and advanced transfer operations.

          • Optionalfilter?: ClientIndexerSearchKeyFilterLike | null

            Optional custom search filter for finding UDT cells. If not provided, a default filter will be created that matches cells with the UDT's type script and valid output data length.

      Returns Udt

      // Basic UDT instance
      const udt = new Udt(
      { txHash: "0x...", index: 0 }, // code outpoint
      { codeHash: "0x...", hashType: "type", args: "0x..." } // type script
      );

      // UDT with SSRI executor for advanced features
      const ssriUdt = new Udt(
      codeOutPoint,
      typeScript,
      { executor: ssriExecutor }
      );

      // UDT with custom filter (advanced usage)
      const customUdt = new Udt(
      codeOutPoint,
      typeScript,
      {
      filter: {
      script: typeScript,
      outputDataLenRange: [16, 32], // Only cells with 16-32 bytes output data
      }
      }
      );

      Default Filter Behavior: If no custom filter is provided, a default filter is created with:

      • script: Set to the provided UDT type script
      • outputDataLenRange: [16, "0xffffffff"] to match valid UDT cells

      SSRI Compliance: When an executor is provided, the UDT instance can use SSRI-compliant features like:

      • Advanced transfer operations
      • Metadata queries (name, symbol, decimals, icon)
      • Custom UDT logic execution

      Legacy Support: Even without an executor, the UDT class supports basic operations for legacy sUDT/xUDT tokens.

    Properties

    script: Script

    The type script that uniquely identifies this UDT token. This script is used to distinguish UDT cells from other cell types and to identify which cells belong to this specific UDT token.

    The script contains:

    • codeHash: Hash of the UDT script code
    • hashType: How the code hash should be interpreted ("type" or "data")
    • args: Arguments that make this UDT unique (often contains token-specific data)
    const udt = new Udt(codeOutPoint, scriptConfig);
    console.log(`UDT script hash: ${udt.script.hash()}`);
    console.log(`UDT args: ${udt.script.args}`);

    // Check if a cell belongs to this UDT
    const isUdt = udt.isUdt(cell);

    The search filter used to find UDT cells controlled by signers. This filter is automatically configured to match cells with this UDT's type script and appropriate output data length (minimum 16 bytes for UDT balance storage).

    The filter includes:

    • script: Set to this UDT's type script
    • outputDataLenRange: [16, "0xffffffff"] to ensure valid UDT cells

    This filter is used internally by methods like:

    • calculateInfo() and calculateBalance() for scanning all UDT cells
    • completeInputs() and related methods for finding suitable input cells
    const udt = new Udt(codeOutPoint, scriptConfig);

    // The filter is used internally, but you can access it if needed
    console.log(`Filter script: ${udt.filter.script?.hash()}`);
    console.log(`Output data range: ${udt.filter.outputDataLenRange}`);

    // Manually find cells using the same filter
    for await (const cell of signer.findCells(udt.filter)) {
    console.log(`Found UDT cell with balance: ${ccc.udtBalanceFrom(cell.outputData)}`);
    }

    Methods

    • Retrieves the human-readable name of the User Defined Token. This method queries the UDT script to get the token's display name, which is typically used in user interfaces and wallets.

      Parameters

      • Optionalcontext: ContextScript

        Optional script execution context for additional parameters

      Returns Promise<ExecutorResponse<undefined | string>>

      A promise resolving to an ExecutorResponse containing the token's name, or undefined if the name is not available or the script doesn't support this method

      const udt = new Udt(codeOutPoint, scriptConfig);
      const nameResponse = await udt.name();
      if (nameResponse.res) {
      console.log(`Token name: ${nameResponse.res}`);
      }
    • Retrieves the symbol (ticker) of the User Defined Token. The symbol is typically a short abbreviation used to identify the token, similar to stock ticker symbols (e.g., "BTC", "ETH", "USDT").

      Parameters

      • Optionalcontext: ContextScript

        Optional script execution context for additional parameters

      Returns Promise<ExecutorResponse<undefined | string>>

      A promise resolving to an ExecutorResponse containing the token's symbol, or undefined if the symbol is not available or the script doesn't support this method

      const udt = new Udt(codeOutPoint, scriptConfig);
      const symbolResponse = await udt.symbol();
      if (symbolResponse.res) {
      console.log(`Token symbol: ${symbolResponse.res}`);
      }
    • Retrieves the number of decimal places for the User Defined Token. This value determines how the token amount should be displayed and interpreted. For example, if decimals is 8, then a balance of 100000000 represents 1.0 tokens.

      Parameters

      • Optionalcontext: ContextScript

        Optional script execution context for additional parameters

      Returns Promise<ExecutorResponse<undefined | bigint>>

      A promise resolving to an ExecutorResponse containing the number of decimals, or undefined if decimals are not specified or the script doesn't support this method

      const udt = new Udt(codeOutPoint, scriptConfig);
      const decimalsResponse = await udt.decimals();
      if (decimalsResponse.res !== undefined) {
      console.log(`Token decimals: ${decimalsResponse.res}`);
      // Convert raw amount to human-readable format
      const humanReadable = rawAmount / (10 ** Number(decimalsResponse.res));
      }
    • Retrieves the icon URL or data URI for the User Defined Token. This can be used to display a visual representation of the token in user interfaces. The returned value may be a URL pointing to an image file or a data URI containing the image data directly.

      Parameters

      • Optionalcontext: ContextScript

        Optional script execution context for additional parameters

      Returns Promise<ExecutorResponse<undefined | string>>

      A promise resolving to an ExecutorResponse containing the icon URL/data, or undefined if no icon is available or the script doesn't support this method

      const udt = new Udt(codeOutPoint, scriptConfig);
      const iconResponse = await udt.icon();
      if (iconResponse.res) {
      // Use the icon in UI
      const imgElement = document.createElement('img');
      imgElement.src = iconResponse.res;
      }
    • Adds the UDT script code as a cell dependency to the transaction. This method ensures that the transaction includes the necessary cell dependency for the UDT script code, which is required for any transaction that uses this UDT.

      Parameters

      Returns Transaction

      A new transaction with the UDT code cell dependency added

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Create a basic transaction
      let tx = ccc.Transaction.from({
      outputs: [{ lock: recipientLock, type: udt.script }],
      outputsData: [ccc.numLeToBytes(100, 16)]
      });

      // Add UDT code dependency
      tx = udt.addCellDeps(tx);

      // Now the transaction can be completed and sent
      await tx.completeInputsByCapacity(signer);
      await tx.completeFeeBy(signer);

      When to Use:

      • When manually constructing transactions that involve UDT cells
      • Before sending any transaction that creates or consumes UDT cells
      • This is automatically called by methods like transfer() and mint()

      Cell Dependency Details:

      • Adds the UDT script code outpoint as a "code" type dependency
      • This allows the transaction to reference and execute the UDT script
      • Required for script validation during transaction processing

      Note: Most high-level UDT methods automatically add this dependency, so manual usage is typically only needed for custom transaction construction.

    • Transfers UDT to specified addresses. This method creates a transaction that transfers UDT tokens to one or more recipients. It can build upon an existing transaction to achieve combined actions.

      Parameters

      • signer: Signer

        The signer that will authorize and potentially pay for the transaction

      • transfers: { to: ScriptLike; amount: NumLike }[]

        Array of transfer operations to perform

      • Optionaltx: null | TransactionLike

        Optional existing transaction to build upon. If not provided, a new transaction will be created

      Returns Promise<ExecutorResponse<Transaction>>

      A promise resolving to an ExecutorResponse containing the transaction with transfer operations

      Mutation - This method represents a mutation of the onchain state and will return a transaction object.

      const { script: change } = await signer.getRecommendedAddressObj();
      const { script: to } = await ccc.Address.fromString(receiver, signer.client);

      const udt = new Udt(
      {
      txHash: "0x4e2e832e0b1e7b5994681b621b00c1e65f577ee4b440ef95fa07db9bb3d50269",
      index: 0,
      },
      {
      codeHash: "0xcc9dc33ef234e14bc788c43a4848556a5fb16401a04662fc55db9bb201987037",
      hashType: "type",
      args: "0x71fd1985b2971a9903e4d8ed0d59e6710166985217ca0681437883837b86162f"
      },
      );

      const { res: tx } = await udt.transfer(
      signer,
      [{ to, amount: 100 }],
      );

      const completedTx = await udt.completeBy(tx, signer);
      await completedTx.completeInputsByCapacity(signer);
      await completedTx.completeFeeBy(signer);
      const transferTxHash = await signer.sendTransaction(completedTx);
    • Mints new tokens to specified addresses. This method creates new UDT tokens and assigns them to the specified recipients. The minting operation requires appropriate permissions and may be restricted based on the UDT's implementation.

      Parameters

      • signer: Signer

        The signer that will authorize and potentially pay for the transaction

      • mints: { to: ScriptLike; amount: NumLike }[]

        Array of mint operations to perform

      • Optionaltx: null | TransactionLike

        Optional existing transaction to build upon. If not provided, a new transaction will be created

      Returns Promise<ExecutorResponse<Transaction>>

      A promise resolving to an ExecutorResponse containing the transaction with mint operations

      Mutation - This method represents a mutation of the onchain state

      const udt = new Udt(codeOutPoint, scriptConfig);
      const { script: recipientLock } = await ccc.Address.fromString(recipientAddress, signer.client);

      const mintResponse = await udt.mint(
      signer,
      [
      { to: recipientLock, amount: ccc.fixedPointFrom(1000) }, // Mint 1000 tokens
      { to: anotherLock, amount: ccc.fixedPointFrom(500) } // Mint 500 tokens
      ]
      );

      // Complete the transaction
      const tx = mintResponse.res;
      await tx.completeInputsByCapacity(signer);
      await tx.completeFeeBy(signer, changeLock);

      const txHash = await signer.sendTransaction(tx);

      May throw if the signer doesn't have minting permissions or if the UDT doesn't support minting

    • Checks if a cell is a valid UDT cell for this token. A valid UDT cell must have this UDT's type script and contain at least 16 bytes of output data (the minimum required for storing the UDT balance as a 128-bit little-endian integer).

      Parameters

      Returns boolean

      True if the cell is a valid UDT cell for this token, false otherwise

      const udt = new Udt(codeOutPoint, scriptConfig);
      const cellOutput = { lock: someLock, type: udt.script };
      const outputData = ccc.numLeToBytes(1000, 16); // 1000 UDT balance

      const isValid = udt.isUdt({ cellOutput, outputData });
      console.log(`Is valid UDT cell: ${isValid}`); // true

      The method checks two conditions:

      1. The cell's type script matches this UDT's script
      2. The output data is at least 16 bytes long (required for UDT balance storage)
    • Retrieves comprehensive information about UDT inputs in a transaction. This method analyzes all input cells and returns detailed statistics including total UDT balance, total capacity occupied, and the number of UDT cells.

      Parameters

      Returns Promise<{ balance: bigint; capacity: bigint; count: number }>

      A promise resolving to an object containing: - balance: Total UDT balance from all input cells - capacity: Total capacity occupied by all UDT input cells - count: Number of UDT input cells

      const udt = new Udt(codeOutPoint, scriptConfig);
      const tx = ccc.Transaction.from(existingTransaction);

      const inputsInfo = await udt.getInputsInfo(tx, client);
      console.log(`UDT inputs: ${inputsInfo.count} cells`);
      console.log(`Total UDT balance: ${inputsInfo.balance}`);
      console.log(`Total capacity: ${inputsInfo.capacity}`);

      This method provides more comprehensive information than getInputsBalance, making it useful for transaction analysis, fee calculation, and UI display. Only cells with this UDT's type script are included in the statistics.

    • Calculates the total UDT balance from all inputs in a transaction. This method examines each input cell and sums up the UDT amounts for cells that have this UDT's type script.

      Parameters

      Returns Promise<bigint>

      A promise resolving to the total UDT balance from all inputs

      const udt = new Udt(codeOutPoint, scriptConfig);
      const tx = ccc.Transaction.from(existingTransaction);

      const inputBalance = await udt.getInputsBalance(tx, client);
      console.log(`Total UDT input balance: ${inputBalance}`);

      This method only counts inputs that have the same type script as this UDT instance. Inputs without a type script or with different type scripts are ignored.

    • Retrieves comprehensive information about UDT outputs in a transaction. This method analyzes all output cells and returns detailed statistics including total UDT balance, total capacity occupied, and the number of UDT cells.

      Parameters

      • txLike: TransactionLike

        The transaction to analyze

      • _client: Client

        The client parameter (unused for outputs since data is already available)

      Returns Promise<{ balance: bigint; capacity: bigint; count: number }>

      A promise resolving to an object containing: - balance: Total UDT balance from all output cells - capacity: Total capacity occupied by all UDT output cells - count: Number of UDT output cells

      const udt = new Udt(codeOutPoint, scriptConfig);
      const tx = ccc.Transaction.from({
      outputs: [
      { lock: recipientLock, type: udt.script },
      { lock: changeLock, type: udt.script }
      ],
      outputsData: [
      ccc.numLeToBytes(1000, 16), // 1000 UDT to recipient
      ccc.numLeToBytes(500, 16) // 500 UDT as change
      ]
      });

      const outputsInfo = await udt.getOutputsInfo(tx, client);
      console.log(`UDT outputs: ${outputsInfo.count} cells`);
      console.log(`Total UDT balance: ${outputsInfo.balance}`); // 1500
      console.log(`Total capacity: ${outputsInfo.capacity}`);

      This method provides more comprehensive information than getOutputsBalance, making it useful for transaction validation, analysis, and UI display. Only cells with this UDT's type script are included in the statistics. This is an async method for consistency with getInputsInfo, though it doesn't actually need to fetch data since output information is already available.

    • Calculates the total UDT balance from all outputs in a transaction. This method examines each output cell and sums up the UDT amounts for cells that have this UDT's type script.

      Parameters

      • txLike: TransactionLike

        The transaction to analyze

      • client: Client

        The client parameter (passed to getOutputsInfo for consistency)

      Returns Promise<bigint>

      A promise resolving to the total UDT balance from all outputs

      const udt = new Udt(codeOutPoint, scriptConfig);
      const tx = ccc.Transaction.from({
      outputs: [
      { lock: recipientLock, type: udt.script },
      { lock: changeLock, type: udt.script }
      ],
      outputsData: [
      ccc.numLeToBytes(1000, 16), // 1000 UDT to recipient
      ccc.numLeToBytes(500, 16) // 500 UDT as change
      ]
      });

      const outputBalance = await udt.getOutputsBalance(tx, client);
      console.log(`Total UDT output balance: ${outputBalance}`); // 1500

      This method only counts outputs that have the same type script as this UDT instance. Outputs without a type script or with different type scripts are ignored. This method is a convenience wrapper around getOutputsInfo that returns only the balance.

    • Calculates the net UDT balance that would be burned (destroyed) in a transaction. This is the difference between the total UDT balance in inputs and outputs. A positive value indicates UDT tokens are being burned, while a negative value indicates more UDT is being created than consumed (which may require minting permissions).

      Parameters

      Returns Promise<bigint>

      A promise resolving to the net UDT balance burned (inputs - outputs)

      const udt = new Udt(codeOutPoint, scriptConfig);
      const tx = ccc.Transaction.from(existingTransaction);

      const burned = await udt.getBalanceBurned(tx, client);
      if (burned > 0) {
      console.log(`${burned} UDT tokens will be burned`);
      } else if (burned < 0) {
      console.log(`${-burned} UDT tokens will be created`);
      } else {
      console.log('UDT balance is conserved');
      }

      This method is useful for:

      • Validating transaction balance conservation
      • Calculating how much UDT is being destroyed in burn operations
      • Detecting minting operations (negative burned balance)
      • Ensuring sufficient UDT inputs are provided for transfers
    • Low-level method to complete UDT inputs for a transaction using a custom accumulator function. This method provides maximum flexibility for input selection by allowing custom logic through the accumulator function. It's primarily used internally by other completion methods.

      Type Parameters

      • T

        The type of the accumulator value

      Parameters

      • txLike: TransactionLike

        The transaction to complete with UDT inputs

      • from: Signer

        The signer that will provide UDT inputs

      • accumulator: (
            acc: T,
            v: Cell,
            i: number,
            array: Cell[],
        ) => undefined | T | Promise<undefined | T>

        Function that determines when to stop adding inputs based on accumulated state

      • init: T

        Initial value for the accumulator

      Returns Promise<{ tx: Transaction; addedCount: number; accumulated?: T }>

      A promise resolving to an object containing: - tx: The transaction with added inputs - addedCount: Number of inputs that were added - accumulated: Final accumulator value (undefined if target was reached)

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Custom accumulator to track both balance and capacity
      const result = await udt.completeInputs(
      tx,
      signer,
      ([balanceAcc, capacityAcc], cell) => {
      const balance = ccc.udtBalanceFrom(cell.outputData);
      const newBalance = balanceAcc + balance;
      const newCapacity = capacityAcc + cell.cellOutput.capacity;

      // Stop when we have enough balance and capacity
      return newBalance >= requiredBalance && newCapacity >= requiredCapacity
      ? undefined // Stop adding inputs
      : [newBalance, newCapacity]; // Continue with updated accumulator
      },
      [ccc.Zero, ccc.Zero] // Initial [balance, capacity]
      );

      This is a low-level method that most users won't need to call directly. Use completeInputsByBalance for typical UDT input completion needs. The accumulator function should return undefined to stop adding inputs, or return an updated accumulator value to continue.

    • Completes UDT inputs for a transaction to satisfy both UDT balance and capacity requirements. This method implements intelligent input selection that considers both UDT token balance and cell capacity constraints, optimizing for minimal cell usage while meeting all requirements. It uses sophisticated balance calculations and early exit optimizations for efficiency.

      Parameters

      • txLike: TransactionLike

        The transaction to complete with UDT inputs

      • from: Signer

        The signer that will provide UDT inputs

      • OptionalbalanceTweak: NumLike

        Optional additional UDT balance requirement beyond outputs (default: 0)

      • OptionalcapacityTweak: NumLike

        Optional additional CKB capacity requirement beyond outputs (default: 0)

      Returns Promise<{ addedCount: number; tx: Transaction }>

      A promise resolving to an object containing: - tx: The modified transaction with added UDT inputs - addedCount: Number of UDT input cells that were added

      When there are insufficient UDT cells to cover the required balance

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Basic usage: add inputs to cover UDT outputs
      const tx = ccc.Transaction.from({
      outputs: [{ lock: recipientLock, type: udt.script }],
      outputsData: [ccc.numLeToBytes(1000, 16)]
      });

      const { tx: completedTx, addedCount } = await udt.completeInputsByBalance(tx, signer);
      console.log(`Added ${addedCount} UDT inputs to cover 1000 UDT requirement`);

      // Advanced usage: with balance and capacity tweaks
      const { tx: advancedTx, addedCount: advancedCount } = await udt.completeInputsByBalance(
      tx,
      signer,
      ccc.numFrom(100), // Extra 100 UDT balance needed
      ccc.fixedPointFrom(5000) // Extra 5000 capacity needed
      );

      This method implements sophisticated dual-constraint input selection with the following logic:

      Balance Calculations:

      • UDT balance deficit: inputBalance - outputBalance - balanceTweak
      • Capacity balance with fee optimization: min(inputCapacity - outputCapacity, estimatedFee) - capacityTweak
      • The capacity calculation tries to avoid extra occupation by UDT cells and compress UDT state

      Early Exit Optimization:

      • Returns immediately with addedCount: 0 if both balance and capacity constraints are satisfied
      • Avoids unnecessary input addition when existing inputs are sufficient

      Smart Input Selection:

      • Uses accumulator pattern to track both UDT balance and capacity during selection
      • Continues adding inputs until both constraints are satisfied: balanceAcc >= 0 && capacityAcc >= 0
      • Prioritizes providing sufficient capacity through UDT cells to avoid extra non-UDT inputs

      Error Handling:

      • Throws ErrorUdtInsufficientCoin with exact shortfall amount if insufficient UDT balance
      • Only throws error if UDT balance cannot be satisfied (capacity issues don't cause errors)
    • Adds ALL available UDT cells from the signer as inputs to the transaction. Unlike completeInputsByBalance which adds only the minimum required inputs, this method collects every available UDT cell that the signer controls, regardless of the transaction's actual UDT requirements.

      Parameters

      • txLike: TransactionLike

        The transaction to add UDT inputs to

      • from: Signer

        The signer that will provide all available UDT inputs

      Returns Promise<{ addedCount: number; tx: Transaction }>

      A promise resolving to an object containing: - tx: The transaction with all available UDT inputs added - addedCount: Number of UDT input cells that were added

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Create a transaction (can be empty or have existing outputs)
      const tx = ccc.Transaction.from({
      outputs: [{ lock: recipientLock, type: udt.script }],
      outputsData: [ccc.numLeToBytes(100, 16)] // Send 100 UDT
      });

      // Add ALL available UDT cells as inputs
      const { tx: completedTx, addedCount } = await udt.completeInputsAll(tx, signer);
      console.log(`Added ${addedCount} UDT cells as inputs`);

      // The transaction now contains all UDT cells the signer controls
      const totalInputBalance = await udt.getInputsBalance(completedTx, client);
      console.log(`Total UDT input balance: ${totalInputBalance}`);

      Use Cases:

      • UDT Consolidation: Combining multiple small UDT cells into fewer larger ones
      • Complete Balance Transfer: Moving all UDT tokens from one address to another
      • Wallet Cleanup: Reducing the number of UDT cells for better wallet performance
      • Batch Operations: When you need to process all UDT holdings at once

      Important Considerations:

      • This method will likely create a large excess balance that needs to be handled with change outputs
      • The resulting transaction may be large and expensive due to many inputs
      • Use completeInputsByBalance instead if you only need specific amounts
      • Always handle the excess balance with appropriate change outputs after calling this method

      Behavior:

      • Adds every UDT cell that the signer controls and that isn't already used in the transaction
      • The accumulator tracks total capacity of added cells (used internally for optimization)
      • Does not stop until all available UDT cells are added
      • Skips cells that are already present as inputs in the transaction
    • Completes a UDT transaction by adding inputs and handling change with a custom change function. This is a low-level method that provides maximum flexibility for handling UDT transaction completion. The change function is called to handle excess UDT balance and can return the capacity cost of the change.

      Parameters

      • txLike: TransactionLike

        The transaction to complete

      • signer: Signer

        The signer that will provide UDT inputs

      • change: (
            tx: Transaction,
            balance: bigint,
            shouldModify: boolean,
        ) => NumLike | Promise<NumLike>

        Function to handle excess UDT balance. Called with (tx, balance, shouldModify) where shouldModify indicates if the function should actually modify the transaction

      • Optionaloptions: { shouldAddInputs?: boolean }

        Optional configuration

        • OptionalshouldAddInputs?: boolean

          Whether to automatically add inputs. Defaults to true

      Returns Promise<Transaction>

      A promise resolving to the completed transaction

      const udt = new Udt(codeOutPoint, scriptConfig);

      const completedTx = await udt.complete(
      tx,
      signer,
      (tx, balance, shouldModify) => {
      if (shouldModify && balance > 0) {
      // Add change output
      const changeData = ccc.numLeToBytes(balance, 16);
      tx.addOutput({ lock: changeLock, type: udt.script }, changeData);
      return ccc.CellOutput.from({ lock: changeLock, type: udt.script }, changeData).capacity;
      }
      return 0;
      }
      );

      The change function is called twice:

      1. First with shouldModify=false to calculate capacity requirements
      2. Then with shouldModify=true to actually modify the transaction This two-phase approach ensures proper input selection considering capacity requirements.
    • Completes a UDT transaction by adding change to an existing output at the specified index. This method modifies an existing UDT output in the transaction to include any excess UDT balance as change, rather than creating a new change output.

      Parameters

      • txLike: TransactionLike

        The transaction to complete

      • signer: Signer

        The signer that will provide UDT inputs

      • indexLike: NumLike

        The index of the output to modify with change balance

      • Optionaloptions: { shouldAddInputs?: boolean }

        Optional configuration

        • OptionalshouldAddInputs?: boolean

          Whether to automatically add inputs. Defaults to true

      Returns Promise<Transaction>

      A promise resolving to the completed transaction

      When the specified output is not a valid UDT cell

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Create transaction with a UDT output that will receive change
      const tx = ccc.Transaction.from({
      outputs: [
      { lock: recipientLock, type: udt.script },
      { lock: changeLock, type: udt.script } // This will receive change
      ],
      outputsData: [
      ccc.numLeToBytes(1000, 16), // Send 1000 UDT
      ccc.numLeToBytes(0, 16) // Change output starts with 0
      ]
      });

      // Complete with change going to output index 1
      const completedTx = await udt.completeChangeToOutput(tx, signer, 1);
      // Output 1 now contains the excess UDT balance

      This method is useful when you want to consolidate change into an existing output rather than creating a new output, which can save on transaction size and fees. The specified output must already be a valid UDT cell with this UDT's type script.

    • Completes a UDT transaction by adding necessary inputs and handling change. This method automatically adds UDT inputs to cover the required output amounts and creates a change output if there's excess UDT balance.

      Parameters

      • tx: TransactionLike

        The transaction to complete, containing UDT outputs

      • signer: Signer

        The signer that will provide UDT inputs

      • changeLike: ScriptLike

        The lock script where any excess UDT balance should be sent as change

      • Optionaloptions: { shouldAddInputs?: boolean }

        Optional configuration for the completion process

        • OptionalshouldAddInputs?: boolean

          Whether to automatically add inputs. Defaults to true

      Returns Promise<Transaction>

      A promise resolving to the completed transaction with inputs and change output added

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Create a transaction with UDT outputs
      const tx = ccc.Transaction.from({
      outputs: [
      { lock: recipientLock, type: udt.script }
      ],
      outputsData: [ccc.numLeToBytes(1000, 16)] // Send 1000 UDT
      });

      // Complete with change going to sender's address
      const { script: changeLock } = await signer.getRecommendedAddressObj();
      const completedTx = await udt.completeChangeToLock(tx, signer, changeLock);

      // The transaction now has:
      // - Sufficient UDT inputs to cover the 1000 UDT output
      // - A change output if there was excess UDT balance

      This method performs the following operations:

      1. Adds UDT inputs using completeInputsByBalance
      2. Calculates the difference between input and output UDT balances
      3. Creates a change output if there's excess UDT balance
    • Completes a UDT transaction using the signer's recommended address for change. This is a convenience method that automatically uses the signer's recommended address as the change destination, making it easier to complete UDT transactions without manually specifying a change address.

      Parameters

      • tx: TransactionLike

        The transaction to complete, containing UDT outputs

      • from: Signer

        The signer that will provide UDT inputs and receive change

      • Optionaloptions: { shouldAddInputs?: boolean }

        Optional configuration for the completion process

        • OptionalshouldAddInputs?: boolean

          Whether to automatically add inputs. Defaults to true

      Returns Promise<Transaction>

      A promise resolving to the completed transaction with inputs and change output added

      const udt = new Udt(codeOutPoint, scriptConfig);

      // Create a transfer transaction
      const transferResponse = await udt.transfer(
      signer,
      [{ to: recipientLock, amount: 1000 }]
      );

      // Complete the transaction (change will go to signer's address)
      const completedTx = await udt.completeBy(transferResponse.res, signer);

      // Add capacity inputs and fee
      await completedTx.completeInputsByCapacity(signer);
      await completedTx.completeFeeBy(signer, changeLock);

      const txHash = await signer.sendTransaction(completedTx);

      completeChangeToLock for more control over the change destination