Skip to content

Commit 21453a7

Browse files
authored
Merge pull request #26 from ora-io/dev
Dev
2 parents 718f580 + cb39096 commit 21453a7

File tree

19 files changed

+338
-42
lines changed

19 files changed

+338
-42
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ora-stack",
3-
"version": "0.2.4",
3+
"version": "0.2.5",
44
"private": true,
55
"packageManager": "[email protected]",
66
"description": "",

packages/orap/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ const store = redisStore()
7878
const sm = new StoreManager(store)
7979

8080
// example event: erc20 transfer
81-
const handle1 = (from: string, to: string, amount: number, event: ContractEventPayload, task: TaskRaplized, next: NextFunction) => {
81+
const handle1 = (from: string, to: string, amount: number, event: ContractEventPayload, next: NextFunction, task: TaskRaplized) => {
8282
console.log(`handle task 1: from ${from} to ${to} amount ${amount} task ${task}`)
8383
next()
8484
}

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.2.4",
4+
"version": "0.2.5",
55
"packageManager": "[email protected]",
66
"description": "",
77
"author": "Norman (nom4dv3), MuRong",

packages/orap/src/flow/event.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { AutoCrossCheckParam, Providers } from '@ora-io/reku'
22
import type { Context } from '../task'
3+
import type { TaskFlowParams } from '../flow/task'
34
import { TaskFlow } from '../flow/task'
4-
import type { StoreManager } from '../store'
5+
import { StoreManager } from '../store'
56
import type { EventSignalRegisterParams } from '../signal'
67
import { EventVerse } from '../verse/event'
78
import type { TaskVerse } from '../verse/task'
@@ -37,13 +38,19 @@ export class EventFlow implements Flow {
3738
return this
3839
}
3940

40-
// task(store: Store, context?: Context): TaskFlow {
41-
task(sm?: StoreManager, context?: Context): TaskFlow {
42-
const tf = new TaskFlow(this)
43-
if (sm)
44-
tf.cache(sm)
45-
if (context)
46-
tf.context(context)
41+
task(params?: TaskFlowParams): TaskFlow
42+
task(sm?: StoreManager | TaskFlowParams, context?: Context): TaskFlow {
43+
let tf: TaskFlow
44+
if (sm instanceof StoreManager) {
45+
tf = new TaskFlow(this)
46+
if (sm)
47+
tf.cache(sm)
48+
if (context)
49+
tf.context(context)
50+
}
51+
else {
52+
tf = new TaskFlow(this, sm)
53+
}
4754
this._taskFlows.push(tf)
4855
return tf
4956
}

packages/orap/src/flow/task.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,26 @@ const defaultHandleFn: HandleFn = () => {
1818
const defaultToKeyFn: ToKeyFn = _ => randomStr(8, alphabetHex)
1919
export interface TaskFlowTTL { taskTtl: Milliseconds; doneTtl: Milliseconds }
2020

21+
export interface TaskFlowParams {
22+
context?: Context
23+
taskPrefix?: Prefix
24+
donePrefix?: Prefix
25+
taskTtl?: Milliseconds
26+
doneTtl?: Milliseconds
27+
cache?: StoreManager
28+
toKeyFn?: ToKeyFn
29+
handleFn?: HandleFn
30+
successFn?: HandleResultFn
31+
failFn?: HandleResultFn
32+
}
33+
2134
// TODO: add 'Failed-Task:' ?
2235
export class TaskFlow implements Flow {
2336
sm: StoreManager = new StoreManager(memoryStore())
2437
taskPrefix: Prefix = 'Task:'
2538
donePrefix: Prefix = 'Done-Task:'
26-
taskTtl?: Milliseconds
27-
doneTtl?: Milliseconds
39+
taskTtl: Milliseconds = 60 * 1000
40+
doneTtl: Milliseconds = 60 * 1000
2841
toKeyFn: ToKeyFn = defaultToKeyFn
2942
handleFn: HandleFn = defaultHandleFn
3043
successFn: HandleResultFn = defaultSuccessFn
@@ -39,7 +52,21 @@ export class TaskFlow implements Flow {
3952

4053
constructor(
4154
private parentFlow: EventFlow,
42-
) { }
55+
params?: TaskFlowParams,
56+
) {
57+
params?.context && this.context(params?.context)
58+
const taskPrefix = params?.taskPrefix ?? this.taskPrefix
59+
const donePrefix = params?.donePrefix ?? this.donePrefix
60+
this.prefix(taskPrefix, donePrefix)
61+
const taskTtl = params?.taskTtl ?? this.taskTtl
62+
const doneTtl = params?.doneTtl ?? this.doneTtl
63+
this.ttl(taskTtl, doneTtl)
64+
params?.cache && this.cache(params?.cache)
65+
params?.toKeyFn && this.key(params?.toKeyFn)
66+
params?.handleFn && this.handle(params?.handleFn)
67+
params?.successFn && this.success(params?.successFn)
68+
params?.failFn && this.fail(params?.failFn)
69+
}
4370

4471
get middlewares() {
4572
return this._middlewares

packages/orap/src/task/verse.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Milliseconds } from '@ora-io/utils'
2-
import { composeFns, isJsonString, isString, stripPrefix } from '@ora-io/utils'
2+
import { argParser, composeFns, isJsonString, isString, stripPrefix } from '@ora-io/utils'
33
import type { TaskFlow } from '../flow'
44
import { HandleSuccessMiddleware } from '../middlewares/HandleSuccessMiddleware'
55
import { HandleFailedMiddleware } from '../middlewares/private'
@@ -97,12 +97,13 @@ export class TaskRaplized extends TaskStorable {
9797
* @returns
9898
*/
9999
toString() {
100-
return this.stringify(this.eventLog)
100+
const res = argParser.parse(this.eventLog)
101+
return this.stringify(res)
101102
}
102103

103104
fromString(jsonString: string) {
104105
if (isJsonString(jsonString))
105-
this.eventLog = JSON.parse(jsonString)
106+
this.eventLog = argParser.serialize(JSON.parse(jsonString))
106107

107108
return this
108109
}

packages/reku/README.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,139 @@ await acc.start({
6868
pollingInterval: 3000,
6969
})
7070
```
71+
72+
73+
## Provider Manager
74+
75+
`RekuProviderManager` is a TypeScript class designed to manage Ethereum providers and contracts. **It supports both WebSocket and JSON-RPC providers, includes heartbeat functionality to maintain the connection, and provides event listening and management features**.
76+
77+
### Usage
78+
79+
#### Import and Initialization
80+
81+
First, import the `RekuProviderManager` class:
82+
83+
```ts
84+
import { RekuProviderManager } from '@ora-io/reku'
85+
```
86+
87+
Then, create an instance of `RekuProviderManager`:
88+
89+
```ts
90+
const providerManager = new RekuProviderManager('wss://your-ethereum-node-url', {
91+
heartbeatInterval: 5000, // Optional, default is 10 seconds
92+
disabledHeartbeat: false // Optional, whether to disable heartbeat
93+
})
94+
```
95+
#### Adding Contracts
96+
97+
You can add a contract using its address and ABI:
98+
99+
```ts
100+
const contractAddress = '0xYourContractAddress'
101+
const contractAbi = [] // Your contract ABI
102+
103+
providerManager.addContract(contractAddress, contractAbi)
104+
```
105+
106+
Or add a contract using an `ethers.Contract` instance:
107+
108+
```ts
109+
const contract = new ethers.Contract(contractAddress, contractAbi, providerManager.provider)
110+
providerManager.addContract(contractAddress, contract)
111+
```
112+
113+
#### Event Listening
114+
115+
Adding Event Listeners
116+
117+
```ts
118+
providerManager.addListener(contractAddress, 'EventName', (event) => {
119+
console.log('Event received:', event)
120+
})
121+
```
122+
123+
Removing Event Listeners
124+
125+
```ts
126+
providerManager.removeListener(contractAddress, 'EventName', listener)
127+
```
128+
129+
Removing All Event Listeners
130+
131+
```ts
132+
providerManager.removeAllListeners()
133+
```
134+
135+
#### Event Management
136+
137+
You can listen for `RekuProviderManager` errors and close events:
138+
139+
```ts
140+
providerManager.on('error', (error) => {
141+
console.error('Provider error:', error)
142+
})
143+
144+
providerManager.on('close', (code, reason) => {
145+
console.log(`Provider closed: ${code} - ${reason}`)
146+
})
147+
```
148+
149+
#### Reconnecting
150+
151+
You can manually reconnect to the provider:
152+
153+
```ts
154+
providerManager.reconnect()
155+
```
156+
157+
#### Destroying
158+
159+
When you no longer need the `RekuProviderManager`, you can destroy it to free up resources:
160+
161+
```ts
162+
providerManager.destroy()
163+
```
164+
165+
### Configuration Options
166+
167+
The `RekuProviderManager` constructor accepts an optional configuration object:
168+
169+
**`heartbeatInterval`**: Heartbeat interval time (in milliseconds), default is 10 seconds.
170+
**`disabledHeartbeat`**: Whether to disable the heartbeat, default is false.
171+
172+
173+
## Contract Manager
174+
175+
176+
The `RekuContractManager` class is designed to manage Ethereum smart contracts using the ethers library. It provides methods to add, remove, and manage event listeners for contract events.
177+
178+
### Example Usage
179+
180+
```ts
181+
import { ethers } from 'ethers'
182+
import { RekuContractManager } from '@ora-io/reku'
183+
184+
const provider = new ethers.providers.WebSocketProvider('wss://your-ethereum-node-url')
185+
const contractAddress = '0xYourContractAddress'
186+
const contractAbi = [] // Your contract ABI
187+
188+
const manager = new RekuContractManager(contractAddress, contractAbi, provider)
189+
190+
// Adding an event listener
191+
manager.addListener('EventName', (event) => {
192+
console.log('Event received:', event)
193+
})
194+
195+
// Removing an event listener
196+
manager.removeListener('EventName', listener)
197+
198+
// Removing all event listeners
199+
manager.removeAllListeners()
200+
201+
// Retrying all event listeners
202+
manager.retryAllListeners()
203+
204+
// Retrying a specific event listener
205+
manager.retryListener('EventName')
206+
```

packages/reku/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/reku",
33
"type": "module",
4-
"version": "0.2.3",
4+
"version": "0.2.4",
55
"packageManager": "[email protected]",
66
"description": "",
77
"author": "Norman (nom4dv3), MuRong",

packages/reku/src/event/crosschecker/autochecker.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ export class AutoCrossChecker extends BaseCrossChecker {
5858

5959
this.cache = new CrossCheckerCacheManager(options?.store, { keyPrefix: options?.storeKeyPrefix, ttl: options?.storeTtl })
6060

61-
let latestblocknum = await timeoutWithRetry(() => this.provider.provider?.getBlockNumber(), 15 * 1000, 3)
61+
let latestBlockNum = await timeoutWithRetry(() => this.provider.provider?.getBlockNumber(), 15 * 1000, 3)
6262

63-
// resume checkpoint priority: options.fromBlock > cache > latestblocknum + 1
64-
const defaultInitCheckpoint = await this.cache.getCheckpoint() ?? (latestblocknum)
63+
// resume checkpoint priority: options.fromBlock > cache > latestBlockNum + 1
64+
const defaultInitCheckpoint = await this.cache.getCheckpoint() ?? (latestBlockNum)
6565

6666
const {
6767
fromBlock = defaultInitCheckpoint,
@@ -87,10 +87,10 @@ export class AutoCrossChecker extends BaseCrossChecker {
8787
}
8888

8989
const waitNextCrosscheck = async (): Promise<boolean> => {
90-
latestblocknum = await timeoutWithRetry(() => this.provider.provider?.getBlockNumber(), 15 * 1000, 3)
91-
if (ccrOptions.toBlock + delayBlockFromLatest > latestblocknum) {
90+
latestBlockNum = await timeoutWithRetry(() => this.provider.provider?.getBlockNumber(), 15 * 1000, 3)
91+
if (ccrOptions.toBlock + delayBlockFromLatest > latestBlockNum) {
9292
// sleep until the toBlock
93-
// await sleep((ccrOptions.toBlock + delayBlockFromLatest - latestblocknum) * blockInterval)
93+
// await sleep((ccrOptions.toBlock + delayBlockFromLatest - latestBlockNum) * blockInterval)
9494
return false
9595
}
9696
return true
@@ -130,7 +130,7 @@ export class AutoCrossChecker extends BaseCrossChecker {
130130
await updateCCROptions(ccrOptions)
131131
}
132132
else {
133-
debug('Because the latest block %d is too old, skip this cross check', latestblocknum)
133+
debug('Because the latest block %d is too old, skip this cross check', latestBlockNum)
134134
}
135135
return endingCondition()
136136
}, pollingInterval)

packages/reku/src/provider/contract.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { ContractAddress, Fn } from '@ora-io/utils'
22
import type { Interface, InterfaceAbi } from 'ethers'
33
import { ethers } from 'ethers'
44

5-
export class ContractManager {
5+
export class RekuContractManager {
66
private _contract?: ethers.Contract
77
private _listeners: Map<ethers.ContractEventName, Fn> = new Map()
88

0 commit comments

Comments
 (0)