@axxel/event-bus 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,12 @@ KAFKA_BROKER="localhost:9092"
40
40
  ### 1️⃣ Producing messages
41
41
 
42
42
  ```ts
43
- import { produceTokenPrice, produceWalletTransaction } from '@axxel/event-bus';
43
+ import {
44
+ produceTokenPrice,
45
+ produceWalletTransaction,
46
+ ensureTokenPriceEvent,
47
+ ensureWalletTransactionEvent,
48
+ } from '@axxel/event-bus';
44
49
 
45
50
  await produceTokenPrice({
46
51
  chainId: 1,
@@ -49,7 +54,8 @@ await produceTokenPrice({
49
54
  price: {
50
55
  USD: { price: 3250.42, exchange: 'uniswap-v3', liquidity: 1250000 },
51
56
  },
52
- marketcap: 1234567890,
57
+ priceInUsd: 3250.42,
58
+ fdvInUsd: 1234567890,
53
59
  symbol: 'WETH',
54
60
  updatedAt: Math.floor(Date.now() / 1000),
55
61
  });
@@ -71,6 +77,19 @@ await produceWalletTransaction({
71
77
  marketcap: 500000000,
72
78
  totalSupply: 1000000,
73
79
  });
80
+
81
+ // Optional: validate and normalize before producing
82
+ const safePricePayload = ensureTokenPriceEvent({
83
+ chainId: 1,
84
+ tokenAddress: '0xC02a...',
85
+ blockNumber: 21345678,
86
+ price: new Map([
87
+ ['USD', { price: 3250.42, exchange: 'uniswap-v3', liquidity: 1250000 }],
88
+ ]),
89
+ priceInUsd: 3250.42,
90
+ fdvInUsd: 1234567890,
91
+ });
92
+ await produceTokenPrice(safePricePayload);
74
93
  ```
75
94
 
76
95
  ---
@@ -126,7 +145,8 @@ interface TokenPriceEvent {
126
145
  tokenAddress: string;
127
146
  blockNumber: number;
128
147
  price: Record<string, PriceInfo> | Map<string, PriceInfo>;
129
- marketcap?: number | null;
148
+ priceInUsd?: number | null;
149
+ fdvInUsd?: number | null;
130
150
  symbol?: string | null;
131
151
  updatedAt?: number;
132
152
  }
@@ -154,6 +174,19 @@ interface WalletTransactionEvent {
154
174
  }
155
175
  ```
156
176
 
177
+ ### Runtime validation helpers
178
+
179
+ Shared Zod schemas are exported to normalize inputs consistently:
180
+
181
+ ```ts
182
+ import { ensureTokenPriceEvent, ensureWalletTransactionEvent } from '@axxel/event-bus';
183
+
184
+ const normalizedPrice = ensureTokenPriceEvent(rawPricePayload);
185
+ const normalizedTx = ensureWalletTransactionEvent(rawTxPayload);
186
+ ```
187
+
188
+ `ensureTokenPriceEvent` accepts either a `Record` or `Map` for `price`, and both helpers lowercase EVM addresses / tx hashes while rejecting malformed numeric fields.
189
+
157
190
  ---
158
191
 
159
192
  ## ⚙️ Environment Variables
@@ -1,3 +1,4 @@
1
1
  export * from './tokenPriceConsumer';
2
2
  export * from './walletTransactionConsumer';
3
+ export * from './tradeExecutionConsumer';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumers/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumers/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./tokenPriceConsumer"), exports);
18
18
  __exportStar(require("./walletTransactionConsumer"), exports);
19
+ __exportStar(require("./tradeExecutionConsumer"), exports);
@@ -0,0 +1,8 @@
1
+ import type { TradeExecutionEvent } from '../types/TradeExecutionEvent';
2
+ /**
3
+ * Start consuming trade execution events.
4
+ * @param groupId - unique consumer group ID
5
+ * @param handler - function to handle each trade execution event
6
+ */
7
+ export declare function startTradeExecutionConsumer(groupId: string, handler: (event: TradeExecutionEvent) => Promise<void> | void): Promise<void>;
8
+ //# sourceMappingURL=tradeExecutionConsumer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tradeExecutionConsumer.d.ts","sourceRoot":"","sources":["../../src/consumers/tradeExecutionConsumer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,iBAqB9D"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startTradeExecutionConsumer = startTradeExecutionConsumer;
4
+ const kafka_1 = require("../config/kafka");
5
+ const topics_1 = require("../topics");
6
+ /**
7
+ * Start consuming trade execution events.
8
+ * @param groupId - unique consumer group ID
9
+ * @param handler - function to handle each trade execution event
10
+ */
11
+ async function startTradeExecutionConsumer(groupId, handler) {
12
+ const consumer = kafka_1.kafka.consumer({ groupId });
13
+ await consumer.connect();
14
+ await consumer.subscribe({
15
+ topic: topics_1.TOPICS.TRADE_EXECUTION,
16
+ fromBeginning: false,
17
+ });
18
+ await consumer.run({
19
+ eachMessage: async ({ message }) => {
20
+ if (!message.value)
21
+ return;
22
+ const event = JSON.parse(message.value.toString());
23
+ await handler(event);
24
+ },
25
+ });
26
+ console.log(`📡 Listening for trade execution events (consumer group: ${groupId})`);
27
+ }
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export * from './validation/tokenPriceEvent.schema';
5
5
  export * from './validation/walletTransactionEvent.schema';
6
6
  export * from './producers/tokenPriceProducer';
7
7
  export * from './producers/walletTransactionProducer';
8
+ export * from './producers/tradeExecutionProducer';
8
9
  export * from './consumers/tokenPriceConsumer';
9
10
  export * from './consumers/walletTransactionConsumer';
11
+ export * from './consumers/tradeExecutionConsumer';
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,qCAAqC,CAAC;AACpD,cAAc,4CAA4C,CAAC;AAE3D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uCAAuC,CAAC;AAEtD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uCAAuC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,qCAAqC,CAAC;AACpD,cAAc,4CAA4C,CAAC;AAE3D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uCAAuC,CAAC;AACtD,cAAc,oCAAoC,CAAC;AAEnD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uCAAuC,CAAC;AACtD,cAAc,oCAAoC,CAAC"}
package/dist/index.js CHANGED
@@ -21,5 +21,7 @@ __exportStar(require("./validation/tokenPriceEvent.schema"), exports);
21
21
  __exportStar(require("./validation/walletTransactionEvent.schema"), exports);
22
22
  __exportStar(require("./producers/tokenPriceProducer"), exports);
23
23
  __exportStar(require("./producers/walletTransactionProducer"), exports);
24
+ __exportStar(require("./producers/tradeExecutionProducer"), exports);
24
25
  __exportStar(require("./consumers/tokenPriceConsumer"), exports);
25
26
  __exportStar(require("./consumers/walletTransactionConsumer"), exports);
27
+ __exportStar(require("./consumers/tradeExecutionConsumer"), exports);
@@ -1,3 +1,4 @@
1
1
  export * from './tokenPriceProducer';
2
2
  export * from './walletTransactionProducer';
3
+ export * from './tradeExecutionProducer';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/producers/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/producers/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./tokenPriceProducer"), exports);
18
18
  __exportStar(require("./walletTransactionProducer"), exports);
19
+ __exportStar(require("./tradeExecutionProducer"), exports);
@@ -0,0 +1,3 @@
1
+ import type { TradeExecutionEvent } from '../types/TradeExecutionEvent';
2
+ export declare function produceTradeExecution(event: TradeExecutionEvent): Promise<void>;
3
+ //# sourceMappingURL=tradeExecutionProducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tradeExecutionProducer.d.ts","sourceRoot":"","sources":["../../src/producers/tradeExecutionProducer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,iBAqBrE"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.produceTradeExecution = produceTradeExecution;
4
+ const kafka_1 = require("../config/kafka");
5
+ const topics_1 = require("../topics");
6
+ async function produceTradeExecution(event) {
7
+ const producer = kafka_1.kafka.producer();
8
+ await producer.connect();
9
+ const key = `${event.chainId}:${event.walletAddress}`;
10
+ await producer.send({
11
+ topic: topics_1.TOPICS.TRADE_EXECUTION,
12
+ messages: [
13
+ {
14
+ key,
15
+ value: JSON.stringify(event),
16
+ },
17
+ ],
18
+ });
19
+ await producer.disconnect();
20
+ console.log(`✅ Execution event added for wallet=${event.walletAddress} on chain=${event.chainId} for ${event.orderType} order of type (${event.type} )`);
21
+ }
package/dist/topics.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export declare const TOPICS: {
2
2
  readonly TOKEN_PRICES: "token-prices";
3
3
  readonly WALLET_TRANSACTIONS: "wallet-transactions";
4
+ readonly TRADE_EXECUTION: "trade-execution";
4
5
  };
5
6
  export type Topic = (typeof TOPICS)[keyof typeof TOPICS];
6
7
  //# sourceMappingURL=topics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"topics.d.ts","sourceRoot":"","sources":["../src/topics.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;CAGT,CAAC;AAEX,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"topics.d.ts","sourceRoot":"","sources":["../src/topics.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAEX,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC"}
package/dist/topics.js CHANGED
@@ -4,4 +4,5 @@ exports.TOPICS = void 0;
4
4
  exports.TOPICS = {
5
5
  TOKEN_PRICES: 'token-prices',
6
6
  WALLET_TRANSACTIONS: 'wallet-transactions',
7
+ TRADE_EXECUTION: 'trade-execution',
7
8
  };
@@ -8,7 +8,8 @@ export interface TokenPriceEvent {
8
8
  tokenAddress: string;
9
9
  blockNumber: number;
10
10
  price: Record<string, PriceInfo> | Map<string, PriceInfo>;
11
- marketcap?: number | null;
11
+ priceInUsd?: number | null;
12
+ fdvInUsd?: number | null;
12
13
  symbol?: string | null;
13
14
  updatedAt?: number;
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TokenPriceEvent.d.ts","sourceRoot":"","sources":["../../src/types/TokenPriceEvent.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IAEpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"TokenPriceEvent.d.ts","sourceRoot":"","sources":["../../src/types/TokenPriceEvent.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IAEpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,15 @@
1
+ export type TradeExecutionEvent = {
2
+ orderId: string;
3
+ userId: string;
4
+ chainId: number;
5
+ tokenAddress: string;
6
+ walletAddress: string;
7
+ amount: string;
8
+ slippage: string;
9
+ mev: boolean;
10
+ totalFee: string;
11
+ type: string;
12
+ executionPriceUsd: string;
13
+ orderType: 'limit' | 'trailing';
14
+ };
15
+ //# sourceMappingURL=TradeExecutionEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TradeExecutionEvent.d.ts","sourceRoot":"","sources":["../../src/types/TradeExecutionEvent.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,GAAG,UAAU,CAAC;CACjC,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,4 @@
1
1
  export * from './TokenPriceEvent';
2
2
  export * from './WalletTransactionEvent';
3
+ export * from './TradeExecutionEvent';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC"}
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./TokenPriceEvent"), exports);
18
18
  __exportStar(require("./WalletTransactionEvent"), exports);
19
+ __exportStar(require("./TradeExecutionEvent"), exports);
@@ -8,7 +8,8 @@ export declare const tokenPriceEventSchema: z.ZodObject<{
8
8
  exchange: z.ZodString;
9
9
  liquidity: z.ZodNumber;
10
10
  }, z.core.$strip>>>>;
11
- marketcap: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
11
+ priceInUsd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
12
+ fdvInUsd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
12
13
  symbol: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
14
  updatedAt: z.ZodOptional<z.ZodNumber>;
14
15
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"tokenPriceEvent.schema.d.ts","sourceRoot":"","sources":["../../src/validation/tokenPriceEvent.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuCxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;iBAQhC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CAE3E"}
1
+ {"version":3,"file":"tokenPriceEvent.schema.d.ts","sourceRoot":"","sources":["../../src/validation/tokenPriceEvent.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiDxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;iBAShC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CAE3E"}
@@ -5,9 +5,9 @@ exports.ensureTokenPriceEvent = ensureTokenPriceEvent;
5
5
  const zod_1 = require("zod");
6
6
  const common_1 = require("./common");
7
7
  const priceEntrySchema = zod_1.z.object({
8
- price: zod_1.z.number().finite(),
8
+ price: zod_1.z.number(),
9
9
  exchange: zod_1.z.string().min(1),
10
- liquidity: zod_1.z.number().finite(),
10
+ liquidity: zod_1.z.number(),
11
11
  });
12
12
  const priceRecordSchema = zod_1.z.preprocess((value) => {
13
13
  if (value instanceof Map) {
@@ -16,7 +16,11 @@ const priceRecordSchema = zod_1.z.preprocess((value) => {
16
16
  if (typeof key !== 'string') {
17
17
  throw new Error(`Invalid price key type: expected string, got ${typeof key}`);
18
18
  }
19
- if (typeof entry === 'object' && entry !== null && 'price' in entry && 'exchange' in entry && 'liquidity' in entry) {
19
+ if (typeof entry === 'object' &&
20
+ entry !== null &&
21
+ 'price' in entry &&
22
+ 'exchange' in entry &&
23
+ 'liquidity' in entry) {
20
24
  normalized[key] = {
21
25
  price: Number(entry.price),
22
26
  exchange: String(entry.exchange),
@@ -38,7 +42,8 @@ exports.tokenPriceEventSchema = zod_1.z.object({
38
42
  tokenAddress: common_1.addressSchema,
39
43
  blockNumber: zod_1.z.number().int().min(0),
40
44
  price: priceRecordSchema,
41
- marketcap: zod_1.z.number().nullable().optional(),
45
+ priceInUsd: zod_1.z.number().nullable().optional(),
46
+ fdvInUsd: zod_1.z.number().nullable().optional(),
42
47
  symbol: zod_1.z.string().nullable().optional(),
43
48
  updatedAt: zod_1.z.number().int().min(0).optional(),
44
49
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axxel/event-bus",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Axxel Kafka Event Bus SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",