diff --git a/packages/xrpl/src/models/common/index.ts b/packages/xrpl/src/models/common/index.ts index 3c302baa..a34e058a 100644 --- a/packages/xrpl/src/models/common/index.ts +++ b/packages/xrpl/src/models/common/index.ts @@ -97,7 +97,7 @@ export interface Hook { * The object that describes the hook in Hooks. */ Hook: { - HookHash: string + HookHash?: string /** * The code that is executed when the hook is triggered. */ diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index f9eb9524..dd34f20d 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -4,7 +4,13 @@ import { TRANSACTION_TYPES } from '@transia/ripple-binary-codec' import { ValidationError } from '../../errors' -import { Amount, IssuedCurrencyAmount, Memo, Signer } from '../common' +import { + Amount, + HookParameter, + IssuedCurrencyAmount, + Memo, + Signer, +} from '../common' import { onlyHasFields } from '../utils' const MEMO_SIZE = 3 @@ -163,6 +169,10 @@ export interface BaseTransaction { * The network id of the transaction. */ NetworkID?: number + /** + * The hook parameters of the transaction. + */ + HookParameters?: HookParameter[] } /** diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 27762509..a05db998 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -43,7 +43,7 @@ export { export { PaymentChannelCreate } from './paymentChannelCreate' export { PaymentChannelFund } from './paymentChannelFund' export { SetRegularKey } from './setRegularKey' -export { SetHook } from './setHook' +export { SetHookFlagsInterface, SetHookFlags, SetHook } from './setHook' export { SignerListSet } from './signerListSet' export { TicketCreate } from './ticketCreate' export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet' diff --git a/packages/xrpl/src/models/transactions/setHook.ts b/packages/xrpl/src/models/transactions/setHook.ts index e7f334ba..f722bc67 100644 --- a/packages/xrpl/src/models/transactions/setHook.ts +++ b/packages/xrpl/src/models/transactions/setHook.ts @@ -1,7 +1,30 @@ import { ValidationError } from '../../errors' import { Hook } from '../common' -import { BaseTransaction, validateBaseTransaction } from './common' +import { BaseTransaction, GlobalFlags, validateBaseTransaction } from './common' + +/** + * Enum representing values for Set Hook Transaction Flags. + * + * @category Transaction Flags + */ +export enum SetHookFlags { + /** + */ + hsfOverride = 0x00000001, + /** + */ + hsfNSDelete = 0x00000010, + /** + */ + hsfCollect = 0x00000100, +} + +export interface SetHookFlagsInterface extends GlobalFlags { + hsfOverride?: boolean + hsfNSDelete?: boolean + hsfCollect?: boolean +} /** * @@ -14,6 +37,8 @@ export interface SetHook extends BaseTransaction { * */ Hooks: Hook[] + + Flags?: number | SetHookFlagsInterface } const MAX_HOOKS = 4 diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index 9ec3beed..19361c84 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -13,6 +13,7 @@ import { DepositPreauth, validateDepositPreauth } from './depositPreauth' import { EscrowCancel, validateEscrowCancel } from './escrowCancel' import { EscrowCreate, validateEscrowCreate } from './escrowCreate' import { EscrowFinish, validateEscrowFinish } from './escrowFinish' +import { Invoke, validateInvoke } from './invoke' import { TransactionMetadata } from './metadata' import { NFTokenAcceptOffer, @@ -62,6 +63,7 @@ export type Transaction = | EscrowCancel | EscrowCreate | EscrowFinish + | Invoke | NFTokenAcceptOffer | NFTokenBurn | NFTokenCancelOffer @@ -142,6 +144,10 @@ export function validate(transaction: Record): void { validateEscrowFinish(tx) break + case 'Invoke': + validateInvoke(tx) + break + case 'NFTokenAcceptOffer': validateNFTokenAcceptOffer(tx) break diff --git a/packages/xrpl/src/models/utils/flags.ts b/packages/xrpl/src/models/utils/flags.ts index f185c99b..c072edc7 100644 --- a/packages/xrpl/src/models/utils/flags.ts +++ b/packages/xrpl/src/models/utils/flags.ts @@ -20,6 +20,7 @@ import { PaymentChannelClaimFlagsInterface, PaymentChannelClaimFlags, } from '../transactions/paymentChannelClaim' +import { SetHookFlagsInterface, SetHookFlags } from '../transactions/setHook' import type { Transaction } from '../transactions/transaction' import { TrustSetFlagsInterface, TrustSetFlags } from '../transactions/trustSet' @@ -75,6 +76,15 @@ export function setTransactionFlagsToNumber(tx: Transaction): void { case 'TrustSet': tx.Flags = convertTrustSetFlagsToNumber(tx.Flags) return + case 'SetHook': + tx.Flags = convertSetHookFlagsToNumber(tx.Flags) + tx.Hooks.forEach((h) => { + h.Hook.Flags = convertSetHookFlagsToNumber( + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- idk + h.Hook.Flags as SetHookFlagsInterface, + ) + }) + return default: tx.Flags = 0 } @@ -108,6 +118,10 @@ function convertTrustSetFlagsToNumber(flags: TrustSetFlagsInterface): number { return reduceFlags(flags, TrustSetFlags) } +function convertSetHookFlagsToNumber(flags: SetHookFlagsInterface): number { + return reduceFlags(flags, SetHookFlags) +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any -- added ValidationError check for flagEnum function reduceFlags(flags: GlobalFlags, flagEnum: any): number { return Object.keys(flags).reduce((resultFlags, flag) => { diff --git a/packages/xrpl/src/utils/hooks.ts b/packages/xrpl/src/utils/hooks.ts index b6c1a40d..55c56bf3 100644 --- a/packages/xrpl/src/utils/hooks.ts +++ b/packages/xrpl/src/utils/hooks.ts @@ -4,9 +4,11 @@ * This module contains the transaction types and the function to calculate the hook on */ -// eslint-disable-next-line @typescript-eslint/no-require-imports -- Required +import { + TRANSACTION_TYPES, + TRANSACTION_TYPE_MAP, +} from '@transia/ripple-binary-codec' import createHash = require('create-hash') -import { TRANSACTION_TYPES, TRANSACTION_TYPE_MAP } from '@transia/ripple-binary-codec' import { XrplError } from '../errors' import { HookParameter } from '../models/common' @@ -42,7 +44,7 @@ export function calculateHookOn(arr: Array): string { `invalid transaction type '${String(nth)}' in HookOn array`, ) } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Required + const tts: Record = TRANSACTION_TYPE_MAP let value = BigInt(hash) // eslint-disable-next-line no-bitwise -- Required @@ -84,6 +86,14 @@ export async function hexNamespace(namespace: string): Promise { return (await sha256(namespace)).toUpperCase() } +function isHex(value: string): boolean { + return /^[0-9A-F]+$/iu.test(value) +} + +function hexValue(value: string): string { + return Buffer.from(value, 'utf8').toString('hex').toUpperCase() +} + /** * Calculate the hex of the hook parameters * @@ -93,20 +103,21 @@ export async function hexNamespace(namespace: string): Promise { export function hexHookParameters(data: HookParameter[]): HookParameter[] { const hookParameters: HookParameter[] = [] for (const parameter of data) { + let hookPName = parameter.HookParameter.HookParameterName + let hookPValue = parameter.HookParameter.HookParameterValue + + if (!isHex(hookPName)) { + hookPName = hexValue(hookPName) + } + + if (!isHex(hookPValue)) { + hookPValue = hexValue(hookPValue) + } + hookParameters.push({ HookParameter: { - HookParameterName: Buffer.from( - parameter.HookParameter.HookParameterName, - 'utf8', - ) - .toString('hex') - .toUpperCase(), - HookParameterValue: Buffer.from( - parameter.HookParameter.HookParameterValue, - 'utf8', - ) - .toString('hex') - .toUpperCase(), + HookParameterName: hookPName, + HookParameterValue: hookPValue, }, }) }