> ## Documentation Index
> Fetch the complete documentation index at: https://paralens.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Enrich DeFi Transaction History Using ParaLens API

> Replace raw tx hashes in your wallet or portfolio app with human-readable labels like 'Swap via aggregator', 'Lending deposit', or 'Liquidity removal'.

Wallet apps and portfolio trackers typically show users a raw list of transaction hashes with hex method IDs and token transfer logs. ParaLens turns each hash into a structured `TxReport` containing a human-readable intent label, the economic actor, token-in/out amounts, a USD net result, and DeFi-specific position context — everything you need to render a meaningful activity feed without writing your own decoder.

## Intent-Based Labeling

Map `classification.intent_kind` to a friendly UI string for the activity feed. The table below covers the most common DeFi operations.

| `intent_kind`        | Suggested UI label  |
| -------------------- | ------------------- |
| `Swap`               | Token swap          |
| `AggregatedSwap`     | Swap via aggregator |
| `LiquidityProvision` | Added liquidity     |
| `LiquidityRemoval`   | Removed liquidity   |
| `LendingDeposit`     | Lending deposit     |
| `LendingWithdraw`    | Lending withdrawal  |
| `Borrow`             | Borrowed funds      |
| `Repay`              | Repaid loan         |
| `BridgeDeposit`      | Bridge deposit      |
| `SimpleTransfer`     | Sent tokens         |

For a complete list of `intent_kind` values see the [Intent Kinds reference](/docs/api-reference/intent-kinds).

<Tip>
  Prefer `classification.intent_label` from the API response for display — it is already human-readable and localization-ready, so you can render it directly without maintaining your own mapping table.
</Tip>

## Position Effects

For lending, borrowing, and liquidity transactions, `position_effects[]` provides DeFi-specific context that goes beyond a simple send/receive summary. Each entry describes how the transaction changed a subject's standing in a protocol.

```json theme={null}
"position_effects": [
  {
    "subject": "0xabc...123",
    "effect": "Increase",
    "kind": "Collateral"
  },
  {
    "subject": "0xabc...123",
    "effect": "Increase",
    "kind": "Debt"
  }
]
```

Use these entries to add contextual tags to activity items — for example, "Collateral increased" next to a lending deposit, or "Liquidity added" next to a `LiquidityProvision` event. Filter `position_effects` by `subject` to scope context to the economic actor rather than protocol contracts.

## Token Flow Summary

`economics.token_in` and `economics.token_out` give you the primary input and output tokens as a ready-to-render pair. Use them to build a compact send/receive card:

```typescript theme={null}
function TokenFlowCard({ economics }: { economics: TxReport["economics"] }) {
  return (
    <div className="token-flow">
      {economics.token_in && (
        <div className="outflow">
          <span>Sent</span>
          <strong>
            {economics.token_in.amount} {economics.token_in.symbol}
          </strong>
        </div>
      )}
      {economics.token_out && (
        <div className="inflow">
          <span>Received</span>
          <strong>
            {economics.token_out.amount} {economics.token_out.symbol}
          </strong>
        </div>
      )}
    </div>
  );
}
```

For multi-leg flows (e.g., liquidity provision involving two tokens) use `inventory_deltas[]` filtered by the actor's address to enumerate all movements.

## USD Net Result

`economics.net_usd_before_gas` carries the net economic value of the transaction before gas costs are subtracted. Always check the `available` flag before rendering it — the field is absent or unavailable for transactions where a USD price could not be resolved.

```typescript theme={null}
function NetUsdBadge({ netUsd }: { netUsd: TxReport["economics"]["net_usd_before_gas"] }) {
  if (!netUsd?.available) return null;

  // Detect sign from the formatted text string (e.g. "-$12.00" indicates a loss)
  const isNegative = netUsd.text.startsWith("-") || netUsd.text.startsWith("−");
  return (
    <span className={isNegative ? "badge-red" : "badge-green"}>
      {netUsd.text}
    </span>
  );
}
```

## Handling Unknowns

When `intent_kind` is `UnknownComplexFlow`, ParaLens was unable to resolve the transaction into a named pattern. Rather than showing a blank entry, fall back to the raw evidence:

1. **Show `inventory_deltas`** — list every asset movement grouped by direction (Inflow / Outflow) so the user still sees what tokens moved and the approximate USD value.
2. **Show `motifs`** — list detected structural primitives (e.g., `ProtocolSwap`, `FlashLoan`) as tags. Even when intent resolution fails, motifs often reveal partial structure.
3. **Label the entry** — use a neutral label such as "Complex transaction" or "Unknown interaction" rather than leaving it blank.

```typescript theme={null}
if (report.classification.intent_kind === "UnknownComplexFlow") {
  return (
    <FallbackCard
      label="Complex transaction"
      deltas={report.inventory_deltas}
      motifs={report.motifs}
    />
  );
}
```

## Example: Mapping Intent Kind and Rendering the Financial Summary

The snippet below shows how to map `intent_kind` to a display label and render a complete financial summary row for an activity feed.

```typescript theme={null}
const INTENT_LABELS: Record<string, string> = {
  Swap: "Token swap",
  AggregatedSwap: "Swap via aggregator",
  LiquidityProvision: "Added liquidity",
  LiquidityRemoval: "Removed liquidity",
  LendingDeposit: "Lending deposit",
  LendingWithdraw: "Lending withdrawal",
  Borrow: "Borrowed funds",
  Repay: "Repaid loan",
  BridgeDeposit: "Bridge deposit",
  SimpleTransfer: "Sent tokens",
  UnknownComplexFlow: "Complex transaction",
};

function getIntentLabel(report: TxReport): string {
  // Prefer the API-supplied label — already human-readable
  if (report.classification.intent_label) {
    return report.classification.intent_label;
  }
  // Fall back to local mapping
  return INTENT_LABELS[report.classification.intent_kind] ?? "Transaction";
}

function ActivityRow({ report }: { report: TxReport }) {
  const { economics, classification } = report;
  const label = getIntentLabel(report);

  return (
    <div className="activity-row">
      <span className="intent-label">{label}</span>

      <div className="token-summary">
        {economics.token_in && (
          <span className="outflow">
            −{economics.token_in.amount} {economics.token_in.symbol}
          </span>
        )}
        {economics.token_out && (
          <span className="inflow">
            +{economics.token_out.amount} {economics.token_out.symbol}
          </span>
        )}
      </div>

      {economics.net_usd_before_gas?.available && (
        <span className="net-usd">{economics.net_usd_before_gas.text}</span>
      )}

      {economics.fee_usd?.available && (
        <span className="gas-cost">Gas: {economics.fee_usd.text}</span>
      )}
    </div>
  );
}
```
