Class: BinaryCodec::Issue
- Inherits:
-
SerializedType
- Object
- SerializedType
- BinaryCodec::Issue
- Defined in:
- lib/binary-codec/types/issue.rb
Overview
An asset without an amount: XRP, an issued token, or an MPT.
The width is not fixed, and it cannot be supplied from outside. XRP is the 20 byte currency code on its own, an issued token adds the 20 byte issuer, and an MPT carries the issuer, a reserved placeholder and the four byte issuance sequence. Only the currency code says which of the three it is, so the parser has to read that before it knows how much to consume.
This class used to take a size hint and read a flat 40 bytes, which for an XRP issue swallowed the field that follows - that is why every AMM and XChain fixture decoded with a nil Asset or the wrong door account.
Constant Summary collapse
- CURRENCY_LENGTH =
20- ISSUER_LENGTH =
20- SEQUENCE_LENGTH =
4- MPT_LENGTH =
CURRENCY_LENGTH + ISSUER_LENGTH + SEQUENCE_LENGTH
- NO_ACCOUNT =
The reserved "no account" value. Sitting in the issuer slot, it marks the issue as an MPT rather than as a token issued by that account.
'0000000000000000000000000000000000000001'
Instance Attribute Summary
Attributes inherited from SerializedType
Class Method Summary collapse
- .from(value) ⇒ Object
-
.from_parser(parser, _size_hint = nil) ⇒ Object
The size hint is accepted and ignored: callers cannot know the width, and passing one in is how the fixed 40 byte read came about.
Instance Method Summary collapse
-
#initialize(bytes = nil) ⇒ Issue
constructor
A new instance of Issue.
- #to_json(_definitions = nil, _field_name = nil) ⇒ Object
Methods inherited from SerializedType
from_bytes, from_hex, from_json, get_type_by_name, #to_byte_sink, #to_bytes, #to_hex, #value_of
Constructor Details
#initialize(bytes = nil) ⇒ Issue
Returns a new instance of Issue.
25 26 27 |
# File 'lib/binary-codec/types/issue.rb', line 25 def initialize(bytes = nil) super(bytes || []) end |
Class Method Details
.from(value) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/binary-codec/types/issue.rb', line 29 def self.from(value) return value if value.is_a?(Issue) return Issue.new(hex_to_bytes(value)) if value.is_a?(String) unless value.is_a?(::Hash) raise StandardError, "Cannot construct Issue from #{value.class}" end return Issue.new(mpt_bytes(value['mpt_issuance_id'])) if value['mpt_issuance_id'] bytes = Currency.from(value['currency']).to_bytes bytes += AccountId.from(value['issuer']).to_bytes if value['issuer'] Issue.new(bytes) end |
.from_parser(parser, _size_hint = nil) ⇒ Object
The size hint is accepted and ignored: callers cannot know the width, and passing one in is how the fixed 40 byte read came about.
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/binary-codec/types/issue.rb', line 57 def self.from_parser(parser, _size_hint = nil) return Issue.new([]) if parser.end? currency = parser.read(CURRENCY_LENGTH) return Issue.new(currency) if Currency.new(currency).to_json == 'XRP' issuer = parser.read(ISSUER_LENGTH) bytes = currency + issuer bytes += parser.read(SEQUENCE_LENGTH) if bytes_to_hex(issuer).upcase == NO_ACCOUNT Issue.new(bytes) end |
Instance Method Details
#to_json(_definitions = nil, _field_name = nil) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/binary-codec/types/issue.rb', line 70 def to_json(_definitions = nil, _field_name = nil) return { 'mpt_issuance_id' => mpt_issuance_id } if to_bytes.length == MPT_LENGTH parser = BinaryParser.new(to_hex) currency = Currency.from_parser(parser).to_json # An XRP issue has no issuer. Reporting one means 20 bytes of the next # field were read as an account. return { 'currency' => currency } if currency == 'XRP' { 'currency' => currency, 'issuer' => AccountId.from_parser(parser).to_json } end |