Skip to content

Commit 9a9ea7f

Browse files
authored
Support HookOnV2 (#105)
1 parent 58d0a5b commit 9a9ea7f

4 files changed

Lines changed: 117 additions & 26 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ const hook = createHookPayload({
210210
namespace: 'hook_on_tt', // namespace (ascii)
211211
flags: HookFlags.hsfOverride, // HookFlags
212212
hookOnArray: ['Payment'] // HookOn Transactions
213+
// or you can use the following fields
214+
// hookOnIncomingArray: ['Payment'] // HookOnIncoming Transactions
215+
// hookOnOutgoingArray: ['Invoke'] // HookOnOutgoing Transactions, needs to be different from hookOnIncomingArray.
213216
})
214217
```
215218

src/setHooks.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,41 @@ import { readHookBinaryHexFromNS, hexNamespace } from './utils'
1414
import { appTransaction } from './libs/xrpl-helpers/transaction'
1515
import { appLogger } from './libs/logger'
1616

17-
export interface SetHookPayload {
17+
export interface SetHookPayloadBase {
1818
version?: number | null
1919
hookHash?: string | null
2020
createFile?: string | null
2121
namespace?: string | null
2222
flags?: number | 0
23-
hookOnArray?: string[] | null
2423
hookParams?: HookParameter[] | null
2524
hookGrants?: HookGrant[] | null
2625
hookName?: string | null
2726
fee?: string | null
2827
}
2928

29+
interface SetHookPayloadWithHookOn extends SetHookPayloadBase {
30+
hookOnArray: string[]
31+
hookOnIncomingArray?: never
32+
hookOnOutgoingArray?: never
33+
}
34+
35+
interface SetHookPayloadWithIncomingOutgoing extends SetHookPayloadBase {
36+
hookOnArray?: never
37+
hookOnIncomingArray: string[]
38+
hookOnOutgoingArray: string[]
39+
}
40+
41+
interface SetHookPayloadWithoutHookOn extends SetHookPayloadBase {
42+
hookOnArray?: null
43+
hookOnIncomingArray?: null
44+
hookOnOutgoingArray?: null
45+
}
46+
47+
export type SetHookPayload =
48+
| SetHookPayloadWithHookOn
49+
| SetHookPayloadWithIncomingOutgoing
50+
| SetHookPayloadWithoutHookOn
51+
3052
export function createHookPayload(payload: SetHookPayload): iHook {
3153
const hook: iHook = {}
3254
if (typeof payload.version === 'number') {
@@ -61,6 +83,16 @@ export function createHookPayload(payload: SetHookPayload): iHook {
6183
if (payload.hookOnArray) {
6284
hook.HookOn = calculateHookOn(payload.hookOnArray)
6385
}
86+
if (payload.hookOnIncomingArray) {
87+
hook.HookOnIncoming = calculateHookOn(
88+
(payload as SetHookPayloadWithIncomingOutgoing).hookOnIncomingArray
89+
)
90+
}
91+
if (payload.hookOnOutgoingArray) {
92+
hook.HookOnOutgoing = calculateHookOn(
93+
(payload as SetHookPayloadWithIncomingOutgoing).hookOnOutgoingArray
94+
)
95+
}
6496
if (payload.hookParams) {
6597
hook.HookParameters = hexHookParameters(payload.hookParams)
6698
}

src/types.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import {
55
} from 'xahau/dist/npm/models/common/xahau'
66
import { Client, Transaction, Wallet } from 'xahau'
77

8-
export type iHook = {
8+
interface iHookBase {
99
HookHash?: string
1010
CreateCode?: string
1111
Flags?: number
12-
HookOn?: string
1312
HookNamespace?: string
1413
HookApiVersion?: number
1514
HookParameters?: HookParameter[]
@@ -18,6 +17,29 @@ export type iHook = {
1817
Fee?: string
1918
}
2019

20+
interface iHookWithHookOn extends iHookBase {
21+
HookOn?: string
22+
HookOnIncoming?: never
23+
HookOnOutgoing?: never
24+
}
25+
26+
interface iHookWithIncomingOutgoing extends iHookBase {
27+
HookOn?: never
28+
HookOnIncoming?: string
29+
HookOnOutgoing?: string
30+
}
31+
32+
interface iHookWithoutHookOn extends iHookBase {
33+
HookOn?: undefined
34+
HookOnIncoming?: undefined
35+
HookOnOutgoing?: undefined
36+
}
37+
38+
export type iHook =
39+
| iHookWithHookOn
40+
| iHookWithIncomingOutgoing
41+
| iHookWithoutHookOn
42+
2143
export type SetHookParams = {
2244
client: Client
2345
wallet: Wallet

test/integration-c/setup/setHook.test.ts

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
clearAllHooks,
2323
StateUtility,
2424
padHexString,
25+
createHookPayload,
2526
} from '../../../src'
2627
import {
2728
HookDefinition as LeHookDefinition,
@@ -121,29 +122,29 @@ describe('SetHook - End to End', () => {
121122

122123
describe('SetHook - Fields', () => {
123124
let testContext: XrplIntegrationTestContext
124-
let Hook: iHook
125125

126126
beforeAll(async () => {
127127
testContext = await setupClient(serverUrl)
128128
})
129-
beforeEach(async () => {
130-
Hook = {
131-
CreateCode: readHookBinaryHexFromNS('base', 'wasm'),
132-
Flags: HookFlags.hsfOverride,
133-
HookOn: calculateHookOn(['Invoke']),
134-
HookNamespace: hexNamespace('base'),
135-
HookApiVersion: 0,
136-
} as iHook
129+
afterEach(async () => {
130+
await clearAllHooks({
131+
client: testContext.client,
132+
wallet: testContext.hook1,
133+
} as SetHookParams)
137134
})
138135
afterAll(async () => teardownClient(testContext))
139136

140137
it('sethook - HookName', async () => {
141138
const hookWallet = testContext.hook1
142139
// SETHOOK IN
143-
const hook = {
144-
...Hook,
145-
HookName: convertStringToHex('test'),
146-
} as iHook
140+
const hook = createHookPayload({
141+
version: 0,
142+
createFile: 'base',
143+
namespace: 'base',
144+
flags: HookFlags.hsfOverride,
145+
hookOnArray: ['Invoke'],
146+
hookName: 'test',
147+
})
147148
await setHooks({
148149
client: testContext.client,
149150
wallet: hookWallet,
@@ -200,20 +201,53 @@ describe('SetHook - Fields', () => {
200201
(response.meta as TransactionMetadata).HookExecutions
201202
).toBeDefined()
202203
}
204+
})
203205

204-
const clearHook = {
205-
Flags: HookFlags.hsfNSDelete,
206-
HookNamespace: hexNamespace('base'),
207-
} as iHook
206+
it('sethook - HookOnIncoming/Outgoing', async () => {
207+
const hookWallet = testContext.hook1
208+
// SETHOOK IN
209+
const hook = createHookPayload({
210+
version: 0,
211+
createFile: 'base',
212+
namespace: 'base',
213+
flags: HookFlags.hsfOverride,
214+
hookOnIncomingArray: ['Invoke'],
215+
hookOnOutgoingArray: ['Payment'],
216+
})
208217
await setHooks({
209218
client: testContext.client,
210219
wallet: hookWallet,
211-
hooks: [{ Hook: clearHook }],
212-
} as SetHookParams)
213-
await clearAllHooks({
214-
client: testContext.client,
215-
wallet: testContext.hook1,
220+
hooks: [{ Hook: hook }],
216221
} as SetHookParams)
222+
223+
createHookPayload({
224+
version: 0,
225+
createFile: 'base',
226+
namespace: 'base',
227+
flags: HookFlags.hsfOverride,
228+
hookOnIncomingArray: ['Invoke'],
229+
hookOnOutgoingArray: ['Payment'],
230+
})
231+
232+
// VALIDATION
233+
const hookReq: LedgerEntryRequest = {
234+
command: 'ledger_entry',
235+
hook: {
236+
account: hookWallet.classicAddress,
237+
},
238+
}
239+
const hookRes = await testContext.client.request(hookReq)
240+
const leHook = hookRes.result.node as LeHook
241+
expect(leHook.Hooks.length).toBe(1)
242+
const hookObj = leHook.Hooks[0].Hook
243+
const hookDefRequest: LedgerEntryRequest = {
244+
command: 'ledger_entry',
245+
hook_definition: hookObj.HookHash,
246+
}
247+
const hookDefRes = await testContext.client.request(hookDefRequest)
248+
const hookDefObj = hookDefRes.result.node as LeHookDefinition
249+
expect(hookDefObj.HookOnIncoming).toBe(calculateHookOn(['Invoke']))
250+
expect(hookDefObj.HookOnOutgoing).toBe(calculateHookOn(['Payment']))
217251
})
218252
})
219253

0 commit comments

Comments
 (0)