Skip to content

Commit 6cd2578

Browse files
authored
Merge pull request #35 from ora-io/dev
Dev
2 parents ebd591c + 09a453d commit 6cd2578

29 files changed

+1490
-141
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ora-stack",
3-
"version": "0.3.5",
3+
"version": "0.4.0-beta.4",
44
"private": true,
55
"packageManager": "[email protected]",
66
"description": "",
@@ -47,7 +47,8 @@
4747
"publish": "nr prepublishOnly && esno scripts/publish.ts",
4848
"release": "esno scripts/release.ts",
4949
"start": "esno src/index.ts",
50-
"test": "DEBUG=DEBUG:ora-stack:* vitest",
50+
"test": "vitest",
51+
"test:debug": "DEBUG=DEBUG:ora-stack:* vitest",
5152
"typecheck": "tsc --noEmit"
5253
},
5354
"devDependencies": {

packages/orap/examples/declarativeDemo/app.ts

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import type { ContractEventPayload } from 'ethers'
33
import { Logger, objectKeys, randomStr, redisStore } from '@ora-io/utils'
44
import type { ListenOptions, ToKeyFn } from '../../src'
5-
import { CheckTransactionStatus, Orap, StoreManager, getMiddlewareContext } from '../../src'
5+
import { Orap, StoreManager, getMiddlewareContext } from '../../src'
66
import ABI from './erc20.abi.json'
77

88
const MAINNET_USDT_ADDR = '0xdAC17F958D2ee523a2206206994597C13D831ec7'
@@ -24,7 +24,12 @@ export function startDemo(options: ListenOptions, storeConfig?: any) {
2424

2525
const toKey: ToKeyFn = (from: string, _to: string, _amount: number) => `${from}_${randomStr(4)}`
2626

27-
orap.event(eventSignalParam.address, eventSignalParam.abi, eventSignalParam.eventName)
27+
const event = orap.event({
28+
address: eventSignalParam.address,
29+
abi: eventSignalParam.abi,
30+
eventName: eventSignalParam.eventName,
31+
enableSubscribe: false,
32+
})
2833
.crosscheck({
2934
store,
3035
storeKeyPrefix: 'ora-stack:orap:demo:cc:',
@@ -37,31 +42,40 @@ export function startDemo(options: ListenOptions, storeConfig?: any) {
3742
// event hook, not necessary
3843
.handle(newEventSignalHook)
3944

40-
// add a task
41-
.task()
45+
// add a task
46+
event.task()
4247
.cache(sm)
4348
.key(toKey)
4449
.prefix('ora-stack:orap:demo:TransferTask:', 'ora-stack:orap:demo:Done-TransferTask:')
4550
.ttl({ taskTtl: 120000, doneTtl: 60000 })
46-
.use(CheckTransactionStatus(options.wsProvider))
51+
// .use(CheckTransactionStatus(options.wsProvider))
4752
.handle(handleTask)
4853
// add another task
49-
.another()
50-
.task()
51-
.prefix('ora-stack:orap:demo:AnotherTask:', 'ora-stack:orap:demo:Done-AnotherTask:')
52-
.cache(sm) // rm to use mem by default
53-
.ttl({ taskTtl: 20000, doneTtl: 20000 })
54-
.handle(handleTask_2)
54+
// .another()
55+
// .task()
56+
// .prefix('ora-stack:orap:demo:AnotherTask:', 'ora-stack:orap:demo:Done-AnotherTask:')
57+
// .cache(sm) // rm to use mem by default
58+
// .ttl({ taskTtl: 20000, doneTtl: 20000 })
59+
// .handle(handleTask_2)
5560

5661
// start signal listener
5762
orap.listen(
5863
options,
5964
() => { logger.log('listening on provider.network') },
6065
)
66+
67+
setTimeout(() => {
68+
logger.log('[+] add another address')
69+
event.addresses([
70+
eventSignalParam.address,
71+
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
72+
])
73+
event.restart()
74+
}, 10 * 1000)
6175
}
6276

63-
async function handleTask(from: string, to: string, amount: number, _event: ContractEventPayload) {
64-
logger.log('[+] handleTask: from =', from, 'to =', to, 'amount =', amount)
77+
async function handleTask(from: string, to: string, amount: number, event: ContractEventPayload) {
78+
logger.log('[+] handleTask: from =', from, 'to =', to, 'amount =', amount, 'address =', event.log.address)
6579
const args = objectKeys(arguments).map(k => arguments[k])
6680

6781
const { next } = getMiddlewareContext(...args)
@@ -74,10 +88,10 @@ async function newEventSignalHook(from: string, to: string, amount: number, even
7488
return true // true to continue handle tasks, false to hijack the process.
7589
}
7690

77-
async function handleTask_2(from: string, to: string, amount: number) {
78-
logger.log('[+] handleTask_2: from =', from, 'to =', to, 'amount =', amount)
79-
const args = objectKeys(arguments).map(k => arguments[k])
91+
// async function handleTask_2(from: string, to: string, amount: number) {
92+
// logger.log('[+] handleTask_2: from =', from, 'to =', to, 'amount =', amount)
93+
// const args = objectKeys(arguments).map(k => arguments[k])
8094

81-
const { next } = getMiddlewareContext(...args)
82-
await next()
83-
}
95+
// const { next } = getMiddlewareContext(...args)
96+
// await next()
97+
// }

packages/orap/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@ora-io/orap",
33
"type": "module",
4-
"version": "0.3.5",
4+
"version": "0.4.0-beta.4",
55
"packageManager": "[email protected]",
66
"description": "",
77
"author": "Norman (nom4dv3), MuRong",

packages/orap/src/beat/event.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ export class EventBeat extends EventSignal {
2020
drop() {
2121
this.listen(this.subscribeProvider, this.crosscheckProvider)
2222
}
23+
24+
stop() {
25+
super.stop()
26+
}
2327
}

packages/orap/src/flow/event.test.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { ethers } from 'ethers'
2-
import { beforeEach, describe, expect, it } from 'vitest'
2+
import { beforeEach, describe, expect, it, vi } from 'vitest'
3+
import { EventVerse } from '../verse/event'
4+
import { ERC20_ABI, USDT_ADDRESS } from '../../tests/config'
35
import { OrapFlow } from './orap'
46
import { EventFlow } from './event'
57

@@ -9,7 +11,7 @@ describe('EventFlow', () => {
911

1012
beforeEach(() => {
1113
orapFlow = new OrapFlow()
12-
eventFlow = new EventFlow(orapFlow)
14+
eventFlow = new EventFlow(orapFlow, { address: USDT_ADDRESS, abi: ERC20_ABI, eventName: 'Transfer' })
1315
})
1416

1517
it('should create a task flow', () => {
@@ -48,4 +50,43 @@ describe('EventFlow', () => {
4850
const parentFlow = eventFlow.another()
4951
expect(parentFlow).toBe(orapFlow)
5052
})
53+
54+
it('should stop the EventVerse', () => {
55+
const stopFn = vi.fn()
56+
vi.spyOn(EventVerse.prototype, 'stop').mockImplementation(stopFn)
57+
eventFlow.stop()
58+
expect(stopFn).toHaveBeenCalled()
59+
})
60+
61+
describe('address', () => {
62+
it('should set the address', () => {
63+
const eventFlow = new EventFlow(orapFlow, { address: USDT_ADDRESS, abi: ERC20_ABI, eventName: 'Transfer' })
64+
eventFlow.address('0x1234567890123456789012345678901234567890')
65+
expect(eventFlow.params.address).toEqual(['0x1234567890123456789012345678901234567890'])
66+
})
67+
68+
it.only('should set the array address', () => {
69+
const eventFlow = new EventFlow(orapFlow, { address: [USDT_ADDRESS], abi: ERC20_ABI, eventName: 'Transfer' })
70+
eventFlow.address(1, '0x1234567890123456789012345678901234567890')
71+
expect(eventFlow.params.address).toContainEqual('0x1234567890123456789012345678901234567890')
72+
})
73+
74+
it('should set the address with number', () => {
75+
const eventFlow = new EventFlow(orapFlow, { address: USDT_ADDRESS, abi: ERC20_ABI, eventName: 'Transfer' })
76+
eventFlow.address(1, '0x1234567890123456789012345678901234567890')
77+
expect(eventFlow.params.address).toEqual(['0x1234567890123456789012345678901234567890'])
78+
})
79+
80+
it('should set the addresses with array', () => {
81+
const eventFlow = new EventFlow(orapFlow, { address: USDT_ADDRESS, abi: ERC20_ABI, eventName: 'Transfer' })
82+
eventFlow.addresses(['0x1234567890123456789012345678901234567890'])
83+
expect(eventFlow.params.address).toEqual(['0x1234567890123456789012345678901234567890'])
84+
})
85+
86+
it('should set the addresses with array and number', () => {
87+
const eventFlow = new EventFlow(orapFlow, { address: USDT_ADDRESS, abi: ERC20_ABI, eventName: 'Transfer' })
88+
eventFlow.addresses([USDT_ADDRESS, '0x1234567890123456789012345678901234567890'])
89+
expect(eventFlow.params.address).toEqual([USDT_ADDRESS, '0x1234567890123456789012345678901234567890'])
90+
})
91+
})
5192
})

packages/orap/src/flow/event.ts

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { AutoCrossCheckParam, Providers } from '@ora-io/reku'
2+
import type { ContractAddress } from '@ora-io/utils/src'
23
import type { Context } from '../task'
34
import type { TaskFlowParams } from '../flow/task'
45
import { TaskFlow } from '../flow/task'
@@ -18,11 +19,25 @@ export class EventFlow implements Flow {
1819
private _subscribeProvider?: Providers
1920
private _crosscheckProvider?: Providers
2021

22+
private _verse: EventVerse = new EventVerse(this)
23+
private _addresses: ContractAddress[] = []
24+
private _params: EventSignalRegisterParams
25+
26+
get verse() {
27+
return this._verse
28+
}
29+
30+
get params() {
31+
return this._params
32+
}
33+
2134
constructor(
22-
private parentFlow?: OrapFlow,
23-
public params?: EventSignalRegisterParams,
35+
private parentFlow: OrapFlow,
36+
params: EventSignalRegisterParams,
2437
handleFn?: HandleFn, // return: succ & continue if true, stop if false
2538
) {
39+
this._params = params
40+
this._addresses = Array.isArray(this.params.address) ? this.params.address : [this.params.address]
2641
// Default handleFn
2742
this.handleFn = handleFn ?? (async (..._args: Array<any>) => {
2843
return true
@@ -52,6 +67,7 @@ export class EventFlow implements Flow {
5267
tf = new TaskFlow(this, sm)
5368
}
5469
this._taskFlows.push(tf)
70+
this._verse.setTaskVerses(this._taskFlows.map(flow => flow.verse))
5571
return tf
5672
}
5773

@@ -89,6 +105,48 @@ export class EventFlow implements Flow {
89105
}
90106

91107
another(): OrapFlow {
92-
return this.parentFlow!
108+
return this.parentFlow
109+
}
110+
111+
stop(): this {
112+
this._verse.stop()
113+
return this
114+
}
115+
116+
restart(): this {
117+
if (this.parentFlow.wsProvider)
118+
this._subscribeProvider = this.parentFlow.wsProvider
119+
else
120+
throw new Error('wsProvider is not set, cannot restart')
121+
if (this.parentFlow.httpProvider)
122+
this._crosscheckProvider = this.parentFlow.httpProvider
123+
else
124+
throw new Error('httpProvider is not set, cannot restart')
125+
this._verse.restart()
126+
return this
127+
}
128+
129+
address(_index: number, _address: ContractAddress): this
130+
address(address: ContractAddress): this
131+
address(_first: ContractAddress | number, _second?: ContractAddress): this {
132+
if (typeof _first === 'number') {
133+
if (!_second)
134+
throw new Error('address is required')
135+
if (Array.isArray(this._params.address))
136+
Reflect.set(this._addresses, _first, _second)
137+
138+
else this._addresses = [_second!]
139+
}
140+
else
141+
if (Array.isArray(this._params.address)) { this._addresses = [...new Set([...this._params.address, _first])] }
142+
else { this._addresses = [_first] }
143+
this._params.address = this._addresses
144+
return this
145+
}
146+
147+
addresses(addresses: ContractAddress[]): this {
148+
this._addresses = addresses
149+
this._params.address = this._addresses
150+
return this
93151
}
94152
}

packages/orap/src/flow/orap.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ethers } from 'ethers'
22
import { beforeEach, describe, expect, it, vi } from 'vitest'
33
import { SEPOLIA_HTTP, SEPOLIA_WSS } from '../../tests/config'
4+
import { OrapVerse } from '../verse/orap'
45
import { OrapFlow } from './orap'
56

67
describe('OrapFlow', () => {
@@ -33,4 +34,11 @@ describe('OrapFlow', () => {
3334
expect(eventFlow).toBeDefined()
3435
expect(orapFlow.eventFlows).toContain(eventFlow)
3536
})
37+
38+
it('should stop the OrapVerse', () => {
39+
const stopFn = vi.fn()
40+
vi.spyOn(OrapVerse.prototype, 'stop').mockImplementation(stopFn)
41+
orapFlow.stop()
42+
expect(stopFn).toHaveBeenCalled()
43+
})
3644
})

packages/orap/src/flow/orap.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,31 @@ export class OrapFlow implements Flow {
2222
} = { event: [] }
2323

2424
onListenFn: Fn = () => { }
25+
_wsProvider?: Providers
26+
_httpProvider?: Providers
2527

2628
get eventFlows() {
2729
return this.subflows.event
2830
}
2931

32+
get wsProvider() {
33+
return this._wsProvider
34+
}
35+
36+
get httpProvider() {
37+
return this._httpProvider
38+
}
39+
40+
private _verse: OrapVerse = new OrapVerse(this)
41+
42+
get verse() {
43+
return this._verse
44+
}
45+
3046
event(params: EventSignalRegisterParams, handler?: HandleFn): EventFlow
31-
event(address: ContractAddress, abi: Interface | InterfaceAbi | HandleFn, eventName: string, handler?: HandleFn): EventFlow
32-
event(params: EventSignalRegisterParams | ContractAddress, abi?: Interface | InterfaceAbi | HandleFn, eventName?: string, handler?: HandleFn): EventFlow {
33-
if (typeof params === 'string' || isAddressable(params))
47+
event(address: ContractAddress | ContractAddress[], abi: Interface | InterfaceAbi | HandleFn, eventName: string, handler?: HandleFn): EventFlow
48+
event(params: EventSignalRegisterParams | ContractAddress | ContractAddress[], abi?: Interface | InterfaceAbi | HandleFn, eventName?: string, handler?: HandleFn): EventFlow {
49+
if (typeof params === 'string' || isAddressable(params) || Array.isArray(params))
3450
params = { address: params, abi: abi as Interface | InterfaceAbi, eventName: eventName as string }
3551
else handler = abi as HandleFn
3652

@@ -45,24 +61,37 @@ export class OrapFlow implements Flow {
4561
* @param options
4662
* @param onListenFn
4763
*/
48-
listen(options: ListenOptions, onListenFn?: Fn) {
64+
listen(options: ListenOptions, onListenFn?: Fn): this {
4965
for (const eventFlow of this.subflows.event) {
5066
eventFlow.setSubscribeProvider(options.wsProvider)
5167
if (options.httpProvider)
5268
eventFlow.setCrosscheckProvider(options.httpProvider)
5369
}
70+
this._wsProvider = options.wsProvider
71+
this._httpProvider = options.httpProvider
5472

5573
if (onListenFn)
5674
this.onListenFn = onListenFn
75+
const eventVerses = this.subflows.event.map(flow => flow.verse)
76+
this._verse.setEventVerses(eventVerses)
5777

58-
const orapVerse = this.assemble()
59-
orapVerse.play()
78+
this._verse.play()
6079
this.onListenFn()
80+
return this
81+
}
82+
83+
stop(): this {
84+
this._verse.stop()
85+
return this
86+
}
87+
88+
restart(): this {
89+
this._verse.restart()
90+
return this
6191
}
6292

6393
assemble(): OrapVerse {
6494
const eventVerses = this.subflows.event.map(flow => flow.assemble())
6595
return new OrapVerse(this).setEventVerses(eventVerses)
66-
// this.routes.event.push(es)
6796
}
6897
}

packages/orap/src/flow/task.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { beforeEach, describe, expect, it, vi } from 'vitest'
22
import { memoryStore } from '@ora-io/utils'
33
import { StoreManager } from '../store'
4-
import { EventFlow, TaskFlow } from '.'
4+
import { ERC20_ABI, USDT_ADDRESS } from '../../tests/config'
5+
import { EventFlow, OrapFlow, TaskFlow } from '.'
56

67
describe('TaskFlow', () => {
78
let parentFlow: any
89
let taskFlow: TaskFlow
910

1011
beforeEach(() => {
11-
parentFlow = new EventFlow()
12+
parentFlow = new EventFlow(new OrapFlow(), { address: USDT_ADDRESS, abi: ERC20_ABI, eventName: 'Transfer' })
1213
taskFlow = new TaskFlow(parentFlow)
1314
})
1415

0 commit comments

Comments
 (0)