# PIP-0006 · Common vocabulary for value, rails and amounts

One definition of Asset, Capability, Amount, Fee, RailReference and Party, shared by ADDRESS, REQUEST and SETTLEMENT.

## Why

ADDRESS, REQUEST and SETTLEMENT all describe how value moves: what is accepted, what is owed, what arrived. In 0.3 each object describes it in its own fields. `accepts` entries take either `asset` and `chain` or `rail` and `currency`. Amounts are bare strings beside a separate `currency`. A receipt carries `rail` as free text.

This PIP defines the types once. Every pillar uses them with the same field names, so a reader that parses a capability in `accepts` parses the same capability in a receipt.

It defines vocabulary only. The pillar PIPs ([0008](/pips/0008), [0010](/pips/0010), [0011](/pips/0011)) say where each type appears. [PIP-0007](/pips/0007) holds the registers the types point into.

## Asset

What has value, independently of how it travels.

```json
{ "asset_type": "fiat", "asset_code": "USD" }
```

| Field | Rule |
|---|---|
| `asset_type` | `fiat` or `token`. The set is open: a reader ignores an entry whose `asset_type` it does not know. |
| `asset_code` | Fiat: ISO 4217, upper case. Token: the symbol, upper case (`USDC`, `ETH`, `BTC`). |

## Capability

One way to settle: one rail, one asset. A capability is an entry of `accepts`, and the `via` of an instruction or a receipt.

```json
{
  "rail": "blockchain",
  "chain": { "slug": "base", "caip2": "eip155:8453", "evm": { "chain_id": 8453 } },
  "asset_type": "token",
  "asset_code": "USDC",
  "standard": "erc20",
  "contract": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"
}
```

```json
{ "rail": "sepa-inst", "asset_type": "fiat", "asset_code": "EUR" }
```

| Field | Rule |
|---|---|
| `rail` | Required. An identifier from the rail register ([PIP-0007](/pips/0007)). |
| `chain` | Required when `rail` is `blockchain`, absent otherwise. At least one of `slug`, `caip2`, `evm.chain_id`. `evm` is present only for EVM chains. When several are present they designate the same chain. `name` may be added for display. |
| `asset_type`, `asset_code` | As in Asset. |
| `standard` | Tokens only, required: `native`, `erc20`, `spl`, `trc20`, `tip20`, `stellar-asset`, `sui-coin`, `jetton`, or another value from the chain register. |
| `contract` | Tokens only, required unless `standard` is `native`. In the canonical form of the chain register. |
| `decimals` | Tokens only. Required when the token is not listed in the chain register, absent otherwise. |

Cross-field rules, checked against the registers:

- `asset_type: "fiat"` is not valid on `rail: "blockchain"`. A stablecoin is a `token`.
- `asset_type: "token"` is valid only on `rail: "blockchain"`.
- On a single-currency rail, `asset_code` is that rail's currency.

Several assets, or several rails, are several capabilities. An address that accepts USDC and USDT on Base and EUR over SEPA Instant has three entries. A capability never lists more than one asset: limits, fees and quotes attach to a single capability.

An optional `instrument` on a capability names the real-world claim a representation stands for. [PIP-0012](/pips/0012) defines the field. This version omits it.

## Amount

```json
{ "value": "5000", "asset_type": "fiat", "asset_code": "USD" }
```

- `value` is a decimal string in major units: no exponent, no leading zeros, no trailing zeros after the decimal point. Never a JSON number.
- `value` has no more decimal places than the asset allows: ISO 4217 minor units for fiat, `decimals` for a token. `"5000.001"` in USD is invalid.
- Amount replaces the pair `amount` and `currency` everywhere.

## Fee

```json
{
  "kind": "operator",
  "amount": { "value": "25", "asset_type": "fiat", "asset_code": "USD" },
  "paid_by": "payer"
}
```

| Field | Values |
|---|---|
| `kind` | `network` (the rail or gas), `operator` (a member), `fx` (an exchange margin) |
| `paid_by` | `payer` or `payee` |

## RailReference

An identifier issued by the rail, which lets a reader leave the PATH document and check the rail.

```json
{ "type": "end_to_end_id", "value": "E1234567820260909100412abcdef" }
```

```json
{ "type": "tx_hash", "value": "0x9f…", "index": 3 }
```

`type` is one of the rail's `rail_reference_types` in the register. `index` locates one transfer when a transaction holds several.

## Party

```json
{ "member": "member-a", "address": "path:4a91c2f7e8d3" }
```

`member` is a member slug. `address` is optional. A party never carries a name, an account or a clear identifier.

## References

Each meaning has one name.

| Field | Meaning | Set by |
|---|---|---|
| `reference` | Public identifier of a PATH object, behind `/path/<reference>` | The issuer, from the common generator |
| `order_reference` | The merchant's own reference | The merchant |
| `payment_reference` | The value the payer attaches to the rail transfer (memo, tag, remittance information) | The payee's member, in an instruction |
| `rail_references` | Identifiers the rail issued once it executed | The rail |
| `account_ref` | A member's internal account reference. Never leaves the member. | The member |

`memo`, `source_tx_hash` and `source_reference` are not part of this vocabulary.

## Canonical form

These rules apply before any digest or signature.

| Element | Rule |
|---|---|
| Absent fields | Omitted in Asset, Capability, Amount, Fee and RailReference. Never `null`. |
| `asset_code` | Upper case |
| `contract` | As the chain register states: lower case for EVM chains, native form otherwise |
| `chain.name` | Excluded from commitments |
| `value` | As in Amount |
| Order of `accepts` | Significant. It states the receiver's preference. Never sorted. |
| Serialisation | JCS (RFC 8785), unchanged |

## grammar

An object that carries capabilities or amounts states `grammar: 2`. An object without `grammar` is in the 0.3 shape and is read as such. A reader never reinterprets a signed 0.3 object in this grammar.

## Compatibility

Breaking for every reader of `accepts`, `amount`, `currency` and receipt `rail`. The pillar PIPs list the shape changes. Objects signed in the 0.3 shape remain valid and are replayed as signed.