add new st types

This commit is contained in:
Mayukha Vadari
2022-07-11 17:23:41 -04:00
parent 77199025f1
commit 3a93f60aab
3 changed files with 227 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
import { BinaryParser } from '../serdes/binary-parser'
import { AccountID } from './account-id'
import { JsonObject, SerializedType } from './serialized-type'
import { Buffer } from 'buffer/'
import { IssuedCurrency, IssuedCurrencyObject } from './issued-currency'
/**
* Interface for JSON objects that represent bridges
*/
interface BridgeObject extends JsonObject {
dst_chain_door: string
dst_chain_issue: IssuedCurrencyObject | string
src_chain_door: string
src_chain_issue: IssuedCurrencyObject | string
}
/**
* Type guard for BridgeObject
*/
function isBridgeObject(arg): arg is BridgeObject {
const keys = Object.keys(arg).sort()
return (
keys.length === 4 &&
keys[0] === 'dst_chain_door' &&
keys[1] === 'dst_chain_issue' &&
keys[2] === 'src_chain_door' &&
keys[3] === 'src_chain_issue'
)
}
/**
* Class for serializing/deserializing Bridges
*/
class Bridge extends SerializedType {
static readonly ZERO_Bridge: Bridge = new Bridge(Buffer.alloc(80))
static readonly TYPE_ORDER: { name: string; type: typeof SerializedType }[] =
[
{ name: 'src_chain_door', type: AccountID },
{ name: 'src_chain_issue', type: IssuedCurrency },
{ name: 'dst_chain_door', type: AccountID },
{ name: 'dst_chain_issue', type: IssuedCurrency },
]
constructor(bytes: Buffer) {
super(bytes ?? Bridge.ZERO_Bridge.bytes)
}
/**
* Construct a bridge from a JSON
*
* @param value Bridge or JSON to parse into a Bridge
* @returns A Bridge object
*/
static from<T extends Bridge | BridgeObject>(value: T): Bridge {
if (value instanceof Bridge) {
return value
}
if (isBridgeObject(value)) {
const bytes: Array<Buffer> = []
this.TYPE_ORDER.forEach((item) => {
const { name, type } = item
const object = type.from(value[name])
bytes.push(object.toBytes())
})
return new Bridge(Buffer.concat(bytes))
}
throw new Error('Invalid type to construct a Bridge')
}
/**
* Read a Bridge from a BinaryParser
*
* @param parser BinaryParser to read the Bridge from
* @returns A Bridge object
*/
static fromParser(parser: BinaryParser): Bridge {
const bytes: Array<Buffer> = []
this.TYPE_ORDER.forEach((item) => {
const { type } = item
const object = type.fromParser(parser)
bytes.push(object.toBytes())
})
return new Bridge(Buffer.concat(bytes))
}
/**
* Get the JSON representation of this Bridge
*
* @returns the JSON interpretation of this.bytes
*/
toJSON(): BridgeObject {
const parser = new BinaryParser(this.toString())
const json = {}
Bridge.TYPE_ORDER.forEach((item) => {
const { name, type } = item
const object = type.fromParser(parser).toJSON()
json[name] = object
})
return json as BridgeObject
}
}
export { Bridge, BridgeObject }

View File

@@ -7,10 +7,12 @@ import {
import { AccountID } from './account-id'
import { Amount } from './amount'
import { Blob } from './blob'
import { Bridge } from './bridge'
import { Currency } from './currency'
import { Hash128 } from './hash-128'
import { Hash160 } from './hash-160'
import { Hash256 } from './hash-256'
import { IssuedCurrency } from './issued-currency'
import { PathSet } from './path-set'
import { STArray } from './st-array'
import { STObject } from './st-object'
@@ -24,10 +26,12 @@ const coreTypes = {
AccountID,
Amount,
Blob,
Bridge,
Currency,
Hash128,
Hash160,
Hash256,
IssuedCurrency,
PathSet,
STArray,
STObject,

View File

@@ -0,0 +1,114 @@
import { BinaryParser } from '../serdes/binary-parser'
import { AccountID } from './account-id'
import { Currency } from './currency'
import { JsonObject, SerializedType } from './serialized-type'
import { Buffer } from 'buffer/'
/**
* Interface for JSON objects that represent amounts
*/
interface IssuedCurrencyObject extends JsonObject {
currency: string
issuer: string
}
/**
* Type guard for AmountObject
*/
function isIssuedCurrencyObject(arg): arg is IssuedCurrencyObject {
const keys = Object.keys(arg).sort()
return keys.length === 2 && keys[0] === 'currency' && keys[1] === 'issuer'
}
/**
* Class for serializing/Deserializing Amounts
*/
class IssuedCurrency extends SerializedType {
static readonly ZERO_ISSUED_CURRENCY: IssuedCurrency = new IssuedCurrency(
Buffer.alloc(20),
)
constructor(bytes: Buffer) {
super(bytes ?? IssuedCurrency.ZERO_ISSUED_CURRENCY.bytes)
}
/**
* Construct an amount from an IOU or string amount
*
* @param value An Amount, object representing an IOU, or a string
* representing an integer amount
* @returns An Amount object
*/
static from<T extends IssuedCurrency | IssuedCurrencyObject | string>(
value: T,
): IssuedCurrency {
if (value instanceof IssuedCurrency) {
return value
}
if (typeof value === 'string') {
IssuedCurrency.assertXrpIsValid(value)
const currency = Currency.from(value).toBytes()
return new IssuedCurrency(currency)
}
if (isIssuedCurrencyObject(value)) {
const currency = Currency.from(value.currency).toBytes()
const issuer = AccountID.from(value.issuer).toBytes()
return new IssuedCurrency(Buffer.concat([currency, issuer]))
}
throw new Error('Invalid type to construct an Amount')
}
/**
* Read an amount from a BinaryParser
*
* @param parser BinaryParser to read the Amount from
* @returns An Amount object
*/
static fromParser(parser: BinaryParser): IssuedCurrency {
const currency = parser.read(20)
if (new Currency(currency).toJSON() === 'XRP') {
return new IssuedCurrency(currency)
}
const currencyAndIssuer = [currency, parser.read(20)]
return new IssuedCurrency(Buffer.concat(currencyAndIssuer))
}
/**
* Get the JSON representation of this Amount
*
* @returns the JSON interpretation of this.bytes
*/
toJSON(): IssuedCurrencyObject | string {
const parser = new BinaryParser(this.toString())
const currency = Currency.fromParser(parser) as Currency
if (currency.toJSON() === 'XRP') {
return currency.toJSON()
}
const issuer = AccountID.fromParser(parser) as AccountID
return {
currency: currency.toJSON(),
issuer: issuer.toJSON(),
}
}
/**
* Validate XRP amount
*
* @param value String representing XRP amount
* @returns void, but will throw if invalid amount
*/
private static assertXrpIsValid(value: string): void {
if (value !== 'XRP') {
throw new Error(`${value} is an illegal amount`)
}
}
}
export { IssuedCurrency, IssuedCurrencyObject }