Evolution SDK
ModulesSdkBuilders

sdk/builders/Unfrack.ts

Unfrack overview

Unfrack UTxO Optimization Module

Implements Unfrack.It principles for efficient wallet structure:

  • Token bundling: Group tokens into optimally-sized UTxOs
  • Fungible isolation: Place each fungible token on its own UTxO
  • NFT grouping: Group NFTs by policy ID
  • ADA optimization: Roll up or subdivide ADA-only

Named in respect to the Unfrack.It website


Table of contents


builders

createUnfrackedChangeOutputs

Creates optimal change outputs by distributing change assets across multiple UTxOs.

First Principles:

  1. Single Responsibility: Create valid change outputs that optimally distribute the given assets
  2. Validity Guarantee: All outputs MUST meet their minUTxO requirements (protocol constraint)
  3. Asset Conservation: All input assets must appear in outputs (no assets lost)
  4. Token Separation: Tokens are bundled by policy to avoid mixing unnecessary assets
  5. ADA Efficiency: Remaining ADA is either separated (if significant) or distributed (if small)

Strategy:

  1. No tokens: Return single ADA-only output
  2. With tokens:
    • Create token bundles with minimum required ADA (minUTxO)
    • Calculate remaining ADA after bundles
    • If remaining >= threshold AND affordable: Create separate ADA output (subdivision)
    • Otherwise: Distribute remaining across bundles (spread)

Affordability Check:

Before creating a separate ADA output, verify that:

  • remaining >= subdivideThreshold (user preference)
  • remaining >= minUTxO for ADA-only output (protocol requirement)

If either check fails, fall back to spreading the remaining ADA across token bundles. This ensures all outputs are always valid.

Outputs are sized with codecOptions when given, the options the transaction is encoded with.

Signature

export declare const createUnfrackedChangeOutputs: (
  changeAddress: CoreAddress.Address,
  changeAssets: CoreAssets.Assets,
  options: UnfrackOptions | undefined,
  coinsPerUtxoByte: bigint,
  codecOptions?: CBOR.TxCodecOptions | CBOR.CodecOptions
) => Effect.Effect<ReadonlyArray<TxOut.TransactionOutput>, Error, never>

Added in v2.0.0

utils

TokenBundle (interface)

Bundle result - multiple UTxOs each containing bundled tokens

Signature

export interface TokenBundle {
  readonly tokens: ReadonlyArray<TokenInfo>
  readonly adaAmount: bigint // Minimum ADA for this bundle
}

TokenInfo (interface)

Token classification for unfracking decisions

Signature

export interface TokenInfo {
  readonly policyId: string
  readonly assetName: string
  readonly quantity: bigint
  readonly isFungible: boolean // True if fungible token, false if NFT
}

UnfrackResult (type alias)

Result of unfrack change output creation

Signature

export type UnfrackResult = {
  /**
   * The change outputs if unfrack was affordable, undefined otherwise
   */
  changeOutputs?: ReadonlyArray<TxOut.TransactionOutput>
  /**
   * Total minimum lovelace required for all outputs
   * This is the sum of minUTxO for all N outputs
   */
  totalMinLovelace: bigint
}

calculateAdaSubdivision

Calculate ADA subdivision amounts based on percentages

Signature

export declare const calculateAdaSubdivision: (
  leftoverAda: bigint,
  options: UnfrackOptions
) => Effect.Effect<ReadonlyArray<bigint>, never, never>

calculateTokenBundles

Calculate bundles based on unfrack configuration Now calculates proper minUTxO for each bundle using CBOR, encoded with codecOptions when given

Signature

export declare const calculateTokenBundles: (
  tokens: ReadonlyArray<TokenInfo>,
  options: UnfrackOptions,
  changeAddress: CoreAddress.Address,
  coinsPerUtxoByte: bigint,
  codecOptions?: CBOR.TxCodecOptions | CBOR.CodecOptions
) => Effect.Effect<ReadonlyArray<TokenBundle>, Error, never>

extractTokens

Extract tokens from assets

Signature

export declare const extractTokens: (assets: CoreAssets.Assets) => ReadonlyArray<TokenInfo>

groupByPolicy

Group tokens by policy ID

Signature

export declare const groupByPolicy: (tokens: ReadonlyArray<TokenInfo>) => Map<string, ReadonlyArray<TokenInfo>>

On this page