mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-29 00:25:48 +00:00
refactor: Add common transaction fields Typescript definition (#1507)
refactor: Add common transaction fields Typescript definition (#1507)
This commit is contained in:
committed by
Mayukha Vadari
parent
2347efc7d3
commit
a4207a552b
@@ -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 {
|
||||
|
||||
38
src/models/common/metadata.ts
Normal file
38
src/models/common/metadata.ts
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
131
src/models/transactions/common.ts
Normal file
131
src/models/transactions/common.ts
Normal 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")
|
||||
}
|
||||
28
src/models/transactions/index.ts
Normal file
28
src/models/transactions/index.ts
Normal 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
10
src/models/utils/index.ts
Normal 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))
|
||||
}
|
||||
Reference in New Issue
Block a user