From 6d6b5a5863c00dd39a876b7dd034ebe065826c05 Mon Sep 17 00:00:00 2001 From: Denis Angell Date: Thu, 16 Feb 2023 23:01:08 -0500 Subject: [PATCH] feature `Hooks` update definitions add network id to base transaction add set hook update required update definitions make network id required --- .../src/enums/definitions.json | 80 +++++++++++++++---- packages/xrpl/src/models/common/index.ts | 77 ++++++++++++++++++ .../xrpl/src/models/transactions/common.ts | 4 + .../xrpl/src/models/transactions/index.ts | 1 + .../xrpl/src/models/transactions/setHook.ts | 47 +++++++++++ .../src/models/transactions/transaction.ts | 6 ++ 6 files changed, 198 insertions(+), 17 deletions(-) create mode 100644 packages/xrpl/src/models/transactions/setHook.ts diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index 317e1feb..342d8925 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -48,7 +48,11 @@ "Child": -2, "Nickname": 110, "Contract": 99, - "GeneratorMap": 103 + "GeneratorMap": 103, + "Hook": 72, + "HookState": 118, + "HookDefinition": 68, + "EmittedTxn": 69 }, "FIELDS": [ [ @@ -321,6 +325,16 @@ "type": "UInt16" } ], + [ + "NetworkID", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], [ "Flags", { @@ -891,16 +905,6 @@ "type": "UInt64" } ], - [ - "HookOn", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], [ "HookInstructionCount", { @@ -1151,6 +1155,16 @@ "type": "Hash256" } ], + [ + "HookOn", + { + "nth": 20, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash256" + } + ], [ "Digest", { @@ -1421,6 +1435,16 @@ "type": "Amount" } ], + [ + "HookCallbackFee", + { + "nth": 20, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "PublicKey", { @@ -1801,6 +1825,16 @@ "type": "Vector256" } ], + [ + "HookNamespaces", + { + "nth": 5, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Vector256" + } + ], [ "Paths", { @@ -2176,6 +2210,10 @@ "telCAN_NOT_QUEUE_BLOCKED": -389, "telCAN_NOT_QUEUE_FEE": -388, "telCAN_NOT_QUEUE_FULL": -387, + "telWRONG_NETWORK": -386, + "telREQUIRES_NETWORK_ID": -385, + "telNETWORK_ID_MAKES_TX_NON_CANONICAL": -384, + "telNON_LOCAL_EMITTED_TXN": -383, "temMALFORMED": -299, "temBAD_AMOUNT": -298, @@ -2211,10 +2249,12 @@ "temINVALID_ACCOUNT_ID": -268, "temCANNOT_PREAUTH_SELF": -267, "temINVALID_COUNT": -266, - "temUNCERTAIN": -265, - "temUNKNOWN": -264, - "temSEQ_AND_TICKET": -263, - "temBAD_NFTOKEN_TRANSFER_FEE": -262, + "temHOOK_DATA_TOO_LARGE": -265, + "temHOOK_REJECTED": -264, + "temUNCERTAIN": -263, + "temUNKNOWN": -262, + "temSEQ_AND_TICKET": -261, + "temBAD_NFTOKEN_TRANSFER_FEE": -260, "tefFAILURE": -199, "tefALREADY": -198, @@ -2250,6 +2290,7 @@ "terNO_RIPPLE": -90, "terQUEUED": -89, "terPRE_TICKET": -88, + "terNO_HOOK": -87, "tesSUCCESS": 0, @@ -2291,6 +2332,7 @@ "tecKILLED": 150, "tecHAS_OBLIGATIONS": 151, "tecTOO_SOON": 152, + "tecHOOK_REJECTED": 153, "tecMAX_SEQUENCE_REACHED": 154, "tecNO_SUITABLE_NFTOKEN_PAGE": 155, "tecNFTOKEN_BUY_SELL_MISMATCH": 156, @@ -2298,7 +2340,9 @@ "tecCANT_ACCEPT_OWN_NFTOKEN_OFFER": 158, "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, - "tecINSUFFICIENT_PAYMENT": 161 + "tecINSUFFICIENT_PAYMENT": 161, + "tecREQUIRES_FLAG": 162, + "tecPRECISION_LOSS": 187 }, "TRANSACTION_TYPES": { "Invalid": -1, @@ -2330,8 +2374,10 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, + "Invoke": 99, "EnableAmendment": 100, "SetFee": 101, - "UNLModify": 102 + "UNLModify": 102, + "EmitFailure": 103 } } diff --git a/packages/xrpl/src/models/common/index.ts b/packages/xrpl/src/models/common/index.ts index 2eeb7b17..efafad38 100644 --- a/packages/xrpl/src/models/common/index.ts +++ b/packages/xrpl/src/models/common/index.ts @@ -51,6 +51,83 @@ interface PathStep { export type Path = PathStep[] +/** + * The object that describes the grant in HookGrants. + */ +export interface HookGrant { + /** + * The object that describes the grant in HookGrants. + */ + HookGrant: { + /** + * + */ + HookHash: string + /** + * + */ + Authorize?: string + } +} + +/** + * The object that describes the parameter in HookParameters. + */ +export interface HookParameter { + /** + * The object that describes the parameter in HookParameters. + */ + HookParameter: { + /** + * + */ + HookParameterName: string + /** + * + */ + HookParameterValue: number + } +} + +/** + * The object that describes the hook in Hooks. + */ +export interface Hook { + /** + * The object that describes the hook in Hooks. + */ + Hook: { + /** + * + */ + CreateCode: string + /** + * + */ + Flags: number + /** + * + */ + HookOn?: string + /** + * + */ + HookNamespace?: string + /** + * + */ + HookApiVersion?: number + /** + * + */ + HookParameters?: HookParameter[] + /** + * + */ + HookGrants?: HookGrant[] + } +} + /** * The object that describes the signer in SignerEntries. */ diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 498a2d74..c87374d8 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -159,6 +159,10 @@ export interface BaseTransaction { * account it says it is from. */ TxnSignature?: string + /** + * The network id of the transaction. + */ + NetworkID: string } /** diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 49944424..7c827d3b 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -42,6 +42,7 @@ export { export { PaymentChannelCreate } from './paymentChannelCreate' export { PaymentChannelFund } from './paymentChannelFund' export { SetRegularKey } from './setRegularKey' +export { 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 new file mode 100644 index 00000000..d55fb968 --- /dev/null +++ b/packages/xrpl/src/models/transactions/setHook.ts @@ -0,0 +1,47 @@ +import { ValidationError } from '../../errors' +import { Hook } from '../common' + +import { BaseTransaction, validateBaseTransaction } from './common' + +/** + * + * + * @category Transaction Models + */ +export interface SetHook extends BaseTransaction { + TransactionType: 'SetHook' + /** + * + */ + Hooks: Hook[] +} + +const MAX_HOOKS = 4 + +/** + * Verify the form and type of an SetHook at runtime. + * + * @param tx - An SetHook Transaction. + * @throws When the SetHook is Malformed. + */ +export function validateSetHook(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.Hooks === undefined) { + throw new ValidationError('SetHook: missing field Hooks') + } + + if (!Array.isArray(tx.Hooks)) { + throw new ValidationError('SetHook: invalid Hooks') + } + + if (tx.Hooks.length === 0) { + throw new ValidationError('SetHook: need at least 1 hook in Hooks') + } + + if (tx.Hooks.length > MAX_HOOKS) { + throw new ValidationError( + `SetHook: maximum of ${MAX_HOOKS} hooks allowed in Hooks`, + ) + } +} diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index dfe0ffbb..9ec3beed 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -43,6 +43,7 @@ import { PaymentChannelFund, validatePaymentChannelFund, } from './paymentChannelFund' +import { SetHook, validateSetHook } from './setHook' import { SetRegularKey, validateSetRegularKey } from './setRegularKey' import { SignerListSet, validateSignerListSet } from './signerListSet' import { TicketCreate, validateTicketCreate } from './ticketCreate' @@ -72,6 +73,7 @@ export type Transaction = | PaymentChannelClaim | PaymentChannelCreate | PaymentChannelFund + | SetHook | SetRegularKey | SignerListSet | TicketCreate @@ -188,6 +190,10 @@ export function validate(transaction: Record): void { validateSetRegularKey(tx) break + case 'SetHook': + validateSetHook(tx) + break + case 'SignerListSet': validateSignerListSet(tx) break