@lightsparkdev/lightspark-sdk 0.3.1 → 0.3.3

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.1",
3
+ "version": "0.3.3",
4
4
  "description": "Lightspark JS SDK",
5
5
  "author": "Lightspark Inc.",
6
6
  "keywords": [
@@ -57,37 +57,39 @@
57
57
  ],
58
58
  "scripts": {
59
59
  "build": "tsup --entry src/index.ts --entry src/objects/index.ts --format cjs,esm --dts",
60
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
60
+ "clean": "rm -rf .turbo && rm -rf dist",
61
61
  "dev": "yarn build -- --watch",
62
62
  "docs": "typedoc src",
63
- "format": "npx prettier --write ./src",
64
- "lint": "npx prettier --check ./src",
63
+ "format": "prettier src --check",
64
+ "format:fix": "prettier src --write",
65
+ "lint": "prettier --check ./src",
65
66
  "postversion": "yarn build",
66
- "test": "tsc --noEmit --project tsconfig-test.json && jest --no-cache --runInBand --bail",
67
- "type-check": "tsc --noEmit"
67
+ "test": "jest --no-cache --runInBand --bail",
68
+ "types": "tsc"
68
69
  },
69
70
  "license": "Apache-2.0",
70
71
  "dependencies": {
71
- "@lightsparkdev/core": "0.3.1",
72
+ "@lightsparkdev/core": "0.3.2",
72
73
  "auto-bind": "^5.0.1",
73
74
  "crypto": "^1.0.1",
74
75
  "crypto-browserify": "^3.12.0",
75
76
  "dayjs": "^1.11.7",
76
77
  "graphql": "^16.6.0",
77
78
  "graphql-ws": "^5.11.3",
78
- "typedoc": "^0.24.7",
79
79
  "ws": "^8.12.1",
80
80
  "zen-observable-ts": "^1.1.0"
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
86
  "jest": "^29.4.1",
86
- "prettier": "^2.8.4",
87
- "prettier-plugin-organize-imports": "^3.2.2",
87
+ "prettier": "2.8.7",
88
88
  "ts-jest": "^29.0.5",
89
89
  "ts-node": "^10.9.1",
90
90
  "tsconfig": "*",
91
+ "tsup": "^6.7.0",
92
+ "typedoc": "^0.24.7",
91
93
  "typescript": "^4.9.5"
92
94
  }
93
95
  }
@@ -0,0 +1,26 @@
1
+ import WebhookEventType from "../objects/WebhookEventType.js";
2
+ import { verifyAndParseWebhook } 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 verifyAndParseWebhook(
16
+ Buffer.from(data, "utf-8"),
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 verifyAndParseWebhook = (
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 parseWebhook(data);
25
+ };
26
+
27
+ const parseWebhook = async (data: Uint8Array): Promise<WebhookEvent> => {
28
+ let td = TextDecoder;
29
+ if (typeof td === "undefined") {
30
+ const tdModule = await import("text-encoding");
31
+ td = tdModule.TextDecoder;
32
+ }
33
+ const dataStr = new td().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
+ };