Skip to content
3 changes: 3 additions & 0 deletions packages/ripple-binary-codec/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Fixed
- add `MPTAmount` support in `Issue` (rippled internal type)

## 2.3.0 (2025-2-13)

### Added
Expand Down
42 changes: 33 additions & 9 deletions packages/ripple-binary-codec/src/types/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ import { BinaryParser } from '../serdes/binary-parser'
import { AccountID } from './account-id'
import { Currency } from './currency'
import { JsonObject, SerializedType } from './serialized-type'
import { Hash192 } from './hash-192'

/**
* Interface for JSON objects that represent amounts
*/
interface IssueObject extends JsonObject {
currency: string
currency?: string
issuer?: string
mpt_issuance_id?: string
}

/**
* Type guard for AmountObject
*/
function isIssueObject(arg): arg is IssueObject {
const keys = Object.keys(arg).sort()
if (keys.length === 1) {
return keys[0] === 'currency'
}
return keys.length === 2 && keys[0] === 'currency' && keys[1] === 'issuer'
const isXRP = keys.length === 1 && keys[0] === 'currency'
const isIOU =
keys.length === 2 && keys[0] === 'currency' && keys[1] === 'issuer'
const isMPT = keys.length === 1 && keys[0] === 'mpt_issuance_id'

return isXRP || isIOU || isMPT
}

/**
Expand All @@ -47,12 +51,24 @@ class Issue extends SerializedType {
}

if (isIssueObject(value)) {
const currency = Currency.from(value.currency).toBytes()
if (value.issuer == null) {
if (value.currency) {
const currency = Currency.from(value.currency).toBytes()

//IOU case
if (value.issuer) {
const issuer = AccountID.from(value.issuer).toBytes()
return new Issue(concat([currency, issuer]))
}

//XRP case
return new Issue(currency)
}
const issuer = AccountID.from(value.issuer).toBytes()
return new Issue(concat([currency, issuer]))

// MPT case
if (value.mpt_issuance_id) {
const mptIssuanceIdBytes = Hash192.from(value.mpt_issuance_id).toBytes()
return new Issue(mptIssuanceIdBytes)
}
}

throw new Error('Invalid type to construct an Amount')
Expand All @@ -79,7 +95,15 @@ class Issue extends SerializedType {
* @returns the JSON interpretation of this.bytes
*/
toJSON(): IssueObject {
// If the buffer is exactly 24 bytes, treat it as an MPT amount.
if (this.toBytes.length === Hash192.width) {
return {
mpt_issuance_id: this.toHex().toUpperCase(),
}
}

const parser = new BinaryParser(this.toString())

const currency = Currency.fromParser(parser) as Currency
if (currency.toJSON() === 'XRP') {
return { currency: currency.toJSON() }
Expand Down
Loading