@lightsparkdev/lightspark-sdk 0.3.0 → 0.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightsparkdev/lightspark-sdk",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Lightspark JS SDK",
5
5
  "author": "Lightspark Inc.",
6
6
  "keywords": [
@@ -63,12 +63,12 @@
63
63
  "format": "npx prettier --write ./src",
64
64
  "lint": "npx prettier --check ./src",
65
65
  "postversion": "yarn build",
66
- "test": "tsc --noEmit --project tsconfig-test.json && jest --no-cache --runInBand --bail",
66
+ "test": "jest --no-cache --runInBand --bail",
67
67
  "type-check": "tsc --noEmit"
68
68
  },
69
69
  "license": "Apache-2.0",
70
70
  "dependencies": {
71
- "@lightsparkdev/core": "0.3.0",
71
+ "@lightsparkdev/core": "0.3.1",
72
72
  "auto-bind": "^5.0.1",
73
73
  "crypto": "^1.0.1",
74
74
  "crypto-browserify": "^3.12.0",
@@ -81,11 +81,12 @@
81
81
  },
82
82
  "devDependencies": {
83
83
  "@types/crypto-js": "^4.1.1",
84
+ "@types/jest": "^29.5.2",
84
85
  "@types/ws": "^8.5.4",
85
- "jest": "^29.4.1",
86
+ "jest": "^29.5.0",
86
87
  "prettier": "^2.8.4",
87
88
  "prettier-plugin-organize-imports": "^3.2.2",
88
- "ts-jest": "^29.0.5",
89
+ "ts-jest": "^29.1.0",
89
90
  "ts-node": "^10.9.1",
90
91
  "tsconfig": "*",
91
92
  "typescript": "^4.9.5"
@@ -0,0 +1,26 @@
1
+ import WebhookEventType from "../objects/WebhookEventType.js";
2
+ import { verify_and_parse_webhook } from "../webhooks.js";
3
+
4
+ describe("Webhooks", () => {
5
+ test("should verify and parse webhook data", async () => {
6
+ const eventType = WebhookEventType.NODE_STATUS;
7
+ const eventId = "1615c8be5aa44e429eba700db2ed8ca5";
8
+ const entityId = "lightning_node:01882c25-157a-f96b-0000-362d42b64397";
9
+ const timeStamp = new Date("2023-05-17T23:56:47.874449+00:00");
10
+ const data = `{"event_type": "NODE_STATUS", "event_id": "1615c8be5aa44e429eba700db2ed8ca5", "timestamp": "2023-05-17T23:56:47.874449+00:00", "entity_id": "lightning_node:01882c25-157a-f96b-0000-362d42b64397"}`;
11
+ const hexdigest =
12
+ "62a8829aeb48b4142533520b1f7f86cdb1ee7d718bf3ea15bc1c662d4c453b74";
13
+ const webhookSecret = "3gZ5oQQUASYmqQNuEk0KambNMVkOADDItIJjzUlAWjX";
14
+
15
+ const webhook = await verify_and_parse_webhook(
16
+ new TextEncoder().encode(data),
17
+ hexdigest,
18
+ webhookSecret
19
+ );
20
+
21
+ expect(webhook.entity_id).toBe(entityId);
22
+ expect(webhook.event_id).toBe(eventId);
23
+ expect(webhook.event_type).toBe(eventType);
24
+ expect(webhook.timestamp).toEqual(timeStamp);
25
+ });
26
+ });
package/src/index.ts CHANGED
@@ -3,3 +3,4 @@
3
3
  export * from "./auth/index.js";
4
4
  export { default as LightsparkClient } from "./client.js";
5
5
  export * from "./objects/index.js";
6
+ export * from "./webhooks.js";
@@ -0,0 +1,42 @@
1
+ import { createHmac } from "crypto";
2
+ import { WebhookEventType } from "./objects/WebhookEventType.js";
3
+
4
+ export const WEBHOOKS_SIGNATURE_HEADER = "lightspark-signature";
5
+
6
+ export interface WebhookEvent {
7
+ event_type: WebhookEventType;
8
+ event_id: string;
9
+ timestamp: Date;
10
+ entity_id: string;
11
+ }
12
+
13
+ export const verify_and_parse_webhook = (
14
+ data: Uint8Array,
15
+ hexdigest: string,
16
+ webhook_secret: string
17
+ ): Promise<WebhookEvent> => {
18
+ const sig = createHmac("sha256", webhook_secret).update(data).digest("hex");
19
+
20
+ if (sig.toLowerCase() !== hexdigest.toLowerCase()) {
21
+ throw new Error("Webhook message hash does not match signature");
22
+ }
23
+
24
+ return parse_webhook(data);
25
+ };
26
+
27
+ export const parse_webhook = async (
28
+ data: Uint8Array
29
+ ): Promise<WebhookEvent> => {
30
+ if (typeof TextDecoder === "undefined") {
31
+ const TextDecoder = (await import("text-encoding")).TextDecoder;
32
+ }
33
+ const dataStr = new TextDecoder().decode(data);
34
+ const event = JSON.parse(dataStr);
35
+
36
+ return {
37
+ event_type: WebhookEventType[event.event_type],
38
+ event_id: event.event_id,
39
+ timestamp: new Date(event.timestamp),
40
+ entity_id: event.entity_id,
41
+ };
42
+ };