refactor: Add common transaction fields Typescript definition (#1507)

refactor: Add common transaction fields Typescript definition (#1507)
This commit is contained in:
Nathan Nichols
2021-08-11 17:37:10 -05:00
committed by Mayukha Vadari
parent 2347efc7d3
commit a4207a552b
11 changed files with 822 additions and 285 deletions

View File

@@ -19,6 +19,18 @@ export interface IssuedCurrencyAmount extends IssuedCurrency {
export type Amount = IssuedCurrencyAmount | string
export interface Signer {
Account: string;
TxnSignature: string;
SigningPubKey: string;
}
export interface Memo {
MemoData?: string;
MemoType?: string;
MemoFormat?: string;
}
export type StreamType = "consensus" | "ledger" | "manifests" | "peer_status" | "transactions" | "transactions_proposed" | "server" | "validations"
interface PathStep {

View File

@@ -0,0 +1,38 @@
import { Amount } from ".";
interface CreatedNode {
CreatedNode: {
LedgerEntryType: string
LedgerIndex: string
NewFields: {[field: string]: any}
}
}
interface ModifiedNode {
ModifiedNode: {
LedgerEntryType: string
LedgerIndex: string
FinalFields: {[field: string]: any}
PreviousFields: {[field: string]: any}
PreviousTxnID?: string
PreviouTxnLgrSeq?: number
}
}
interface DeletedNode {
DeletedNode: {
LedgerEntryType: string
LedgerIndex: string
FinalFields: {[field: string]: any}
}
}
type Node = CreatedNode | ModifiedNode | DeletedNode
export default interface Metadata {
AffectedNodes: Node[]
DeliveredAmount?: Amount
delivered_amount?: Amount
TransactionIndex: number
TransactionResult: string
}

View File

@@ -1,5 +1,5 @@
import { LedgerIndex } from "../common";
import { TransactionMetadata } from "../common/transaction";
import Metadata from "../common/metadata";
import { BaseRequest, BaseResponse } from "./baseMethod";
export interface AccountTxRequest extends BaseRequest {
@@ -17,7 +17,7 @@ export interface AccountTxRequest extends BaseRequest {
interface AccountTransaction {
ledger_index: number
meta: string | TransactionMetadata
meta: string | Metadata
tx?: any // TODO: replace when transaction objects are done
tx_blob?: string
validated: boolean

View File

@@ -1,4 +1,4 @@
import { Response } from ".";
import { Request } from './../methods'
export interface BaseRequest {
id: number | string
@@ -21,6 +21,6 @@ export interface BaseResponse {
warnings?: Warning[]
forwarded?: boolean
error?: string
request?: Response
request?: Request
api_version?: number
}

View File

@@ -0,0 +1,131 @@
import { ValidationError } from "../../common/errors"
import { Memo, Signer } from "../common"
import { onlyHasFields } from "../utils"
const transactionTypes = [
"AccountSet",
"AccountDelete",
"CheckCancel",
"CheckCash",
"CheckCreate",
"DepositPreauth",
"EscrowCancel",
"EscrowCreate",
"EscrowFinish",
"OfferCancel",
"OfferCreate",
"Payment",
"PaymentChannelClaim",
"PaymentChannelCreate",
"PaymentChannelFund",
"SetRegularKey",
"SignerListSet",
"TicketCreate",
"TrustSet",
]
const isMemo = (obj: {Memo: Memo}): boolean => {
const memo = obj.Memo
const size = Object.keys(memo).length
const validData = memo.MemoData === undefined
|| typeof memo.MemoData === 'string'
const validFormat = memo.MemoFormat === undefined
|| typeof memo.MemoData === 'string'
const validType = memo.MemoType === undefined
|| typeof memo.MemoType === 'string'
return (1 <= size && size <= 3)
&& validData
&& validFormat
&& validType
&& onlyHasFields(memo, ["MemoFormat", "MemoData", "MemoType"])
}
const isSigner = (signer: Signer): boolean => {
return Object.keys(signer).length === 3
&& typeof signer.Account === 'string'
&& typeof signer.TxnSignature === 'string'
&& typeof signer.SigningPubKey === 'string'
}
export interface CommonFields {
Account: string;
TransactionType: string;
Fee?: string;
Sequence?: number;
AccountTxnID?: string;
Flags?: number;
LastLedgerSequence?: number;
Memos?: Array<{ Memo: Memo }>;
Signers?: Array<Signer>;
SourceTag?: number;
SigningPubKey?: string;
TicketSequence?: number;
TxnSignature?: string;
}
/**
* verify the common fields of a transaction. The verify functionality will be
* optional, and will check transaction form at runtime. This should be called
* any time a transaction will be verified.
*
* @param common - An interface w/ common transaction fields
* @returns - Void
* @throws - When the common param is malformed.
*/
export function verifyCommonFields(common: CommonFields): void {
if (common.Account === undefined)
throw new ValidationError("CommonFields: missing field Account")
if (typeof common.Account !== 'string')
throw new ValidationError("CommonFields: Account not string")
if (common.TransactionType === undefined)
throw new ValidationError("CommonFields: missing field TransactionType")
if (typeof common.TransactionType !== 'string')
throw new ValidationError("CommonFields: TransactionType not string")
if (!transactionTypes.includes(common.TransactionType))
throw new ValidationError("CommonFields: Unknown TransactionType")
if (common.Fee !== undefined && typeof common.Fee !== 'string')
throw new ValidationError("CommonFields: invalid Fee")
if (common.Sequence !== undefined && typeof common.Sequence !== 'number')
throw new ValidationError("CommonFields: invalid Sequence")
if (common.Flags !== undefined && typeof common.Flags !== 'number')
throw new ValidationError("CommonFields: invalid Flags")
if (common.AccountTxnID !== undefined
&& typeof common.AccountTxnID !== 'string')
throw new ValidationError("CommonFields: invalid AccountTxnID")
if (common.LastLedgerSequence !== undefined
&& typeof common.LastLedgerSequence !== 'number')
throw new ValidationError("CommonFields: invalid LastLedgerSequence")
if (common.Memos !== undefined
&& (common.Memos.length === 0 || !common.Memos.every(isMemo)))
throw new ValidationError("CommonFields: invalid Memos")
if (common.Signers !== undefined
&& (common.Signers.length === 0 || !common.Signers.every(isSigner)))
throw new ValidationError("CommonFields: invalid Signers")
if (common.SourceTag !== undefined && typeof common.SourceTag !== 'number')
throw new ValidationError("CommonFields: invalid SourceTag")
if (common.SigningPubKey !== undefined
&& typeof common.SigningPubKey !== 'string')
throw new ValidationError("CommonFields: invalid SigningPubKey")
if (common.TicketSequence !== undefined
&& typeof common.TicketSequence !== 'number')
throw new ValidationError("CommonFields: invalid TicketSequence")
if (common.TxnSignature !== undefined
&& typeof common.TxnSignature !== 'string')
throw new ValidationError("CommonFields: invalid TxnSignature")
}

View File

@@ -0,0 +1,28 @@
import Metadata from "../common/metadata";
export type Transaction = never // (For now)
// AccountSet
// | AccountDelete
// | CheckCancel
// | CheckCash
// | CheckCreate
// | DepositPreauth
// | EscrowCancel
// | EscrowCreate
// | EscrowFinish
// | OfferCancel
// | OfferCreate
// | PaymentTransaction
// | PaymentChannelClaim
// | PaymentChannelCreate
// | PaymentChannelFund
// | SetRegularKey
// | SignerListSet
// | TicketCreate
// | TrustSet
export interface TransactionAndMetadata {
transaction: Transaction;
metadata: Metadata
}

10
src/models/utils/index.ts Normal file
View File

@@ -0,0 +1,10 @@
/**
* Verify that all fields of an object are in fields
*
* @param obj Object to verify fields
* @param fields Fields to verify
* @returns True if keys in object are all in fields
*/
export function onlyHasFields(obj: object, fields: Array<string>): boolean {
return Object.keys(obj).every((key:string) => fields.includes(key))
}