pkg-sdk-test 0.0.18 → 0.0.19
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/dist/cjs/BaseClient.js +2 -2
- package/dist/cjs/api/types/WebhookPaymentEvent.d.ts +26 -0
- package/dist/cjs/api/types/WebhookPaymentEvent.js +12 -0
- package/dist/cjs/api/types/WebhookStaticDepositEvent.d.ts +29 -0
- package/dist/cjs/api/types/WebhookStaticDepositEvent.js +11 -0
- package/dist/cjs/api/types/index.d.ts +2 -0
- package/dist/cjs/api/types/index.js +2 -0
- package/dist/cjs/core/index.d.ts +1 -0
- package/dist/cjs/core/index.js +1 -0
- package/dist/cjs/core/webhooks/computeHmacSignature.d.ts +9 -0
- package/dist/cjs/core/webhooks/computeHmacSignature.js +84 -0
- package/dist/cjs/core/webhooks/fetchJwks.d.ts +15 -0
- package/dist/cjs/core/webhooks/fetchJwks.js +156 -0
- package/dist/cjs/core/webhooks/index.d.ts +8 -0
- package/dist/cjs/core/webhooks/index.js +11 -0
- package/dist/cjs/core/webhooks/timingSafeEqual.d.ts +1 -0
- package/dist/cjs/core/webhooks/timingSafeEqual.js +85 -0
- package/dist/cjs/core/webhooks/types.d.ts +1 -0
- package/dist/cjs/core/webhooks/types.js +2 -0
- package/dist/cjs/core/webhooks/verifyAsymmetricSignature.d.ts +10 -0
- package/dist/cjs/core/webhooks/verifyAsymmetricSignature.js +210 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/webhooks/WebhooksHelper.d.ts +9 -0
- package/dist/cjs/webhooks/WebhooksHelper.js +87 -0
- package/dist/cjs/webhooks/index.d.ts +1 -0
- package/dist/cjs/webhooks/index.js +5 -0
- package/dist/esm/BaseClient.mjs +2 -2
- package/dist/esm/api/types/WebhookPaymentEvent.d.mts +26 -0
- package/dist/esm/api/types/WebhookPaymentEvent.mjs +9 -0
- package/dist/esm/api/types/WebhookStaticDepositEvent.d.mts +29 -0
- package/dist/esm/api/types/WebhookStaticDepositEvent.mjs +8 -0
- package/dist/esm/api/types/index.d.mts +2 -0
- package/dist/esm/api/types/index.mjs +2 -0
- package/dist/esm/core/index.d.mts +1 -0
- package/dist/esm/core/index.mjs +1 -0
- package/dist/esm/core/webhooks/computeHmacSignature.d.mts +9 -0
- package/dist/esm/core/webhooks/computeHmacSignature.mjs +48 -0
- package/dist/esm/core/webhooks/fetchJwks.d.mts +15 -0
- package/dist/esm/core/webhooks/fetchJwks.mjs +153 -0
- package/dist/esm/core/webhooks/index.d.mts +8 -0
- package/dist/esm/core/webhooks/index.mjs +4 -0
- package/dist/esm/core/webhooks/timingSafeEqual.d.mts +1 -0
- package/dist/esm/core/webhooks/timingSafeEqual.mjs +49 -0
- package/dist/esm/core/webhooks/types.d.mts +1 -0
- package/dist/esm/core/webhooks/types.mjs +1 -0
- package/dist/esm/core/webhooks/verifyAsymmetricSignature.d.mts +10 -0
- package/dist/esm/core/webhooks/verifyAsymmetricSignature.mjs +174 -0
- package/dist/esm/index.d.mts +1 -0
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/version.d.mts +1 -1
- package/dist/esm/version.mjs +1 -1
- package/dist/esm/webhooks/WebhooksHelper.d.mts +9 -0
- package/dist/esm/webhooks/WebhooksHelper.mjs +50 -0
- package/dist/esm/webhooks/index.d.mts +1 -0
- package/dist/esm/webhooks/index.mjs +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.verifyAsymmetricSignature = verifyAsymmetricSignature;
|
|
46
|
+
const index_js_1 = require("../runtime/index.js");
|
|
47
|
+
function getNodeAlgorithmName(algorithm) {
|
|
48
|
+
switch (algorithm) {
|
|
49
|
+
case "RSA_SHA256":
|
|
50
|
+
return "RSA-SHA256";
|
|
51
|
+
case "RSA_SHA384":
|
|
52
|
+
return "RSA-SHA384";
|
|
53
|
+
case "RSA_SHA512":
|
|
54
|
+
return "RSA-SHA512";
|
|
55
|
+
case "ECDSA_SHA256":
|
|
56
|
+
return "SHA256";
|
|
57
|
+
case "ECDSA_SHA384":
|
|
58
|
+
return "SHA384";
|
|
59
|
+
case "ECDSA_SHA512":
|
|
60
|
+
return "SHA512";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Each ECDSA curve has a fixed coordinate size for IEEE P1363 format.
|
|
64
|
+
// Web Crypto requires P1363 (r ∥ s), while Node's createVerify accepts DER (ASN.1 SEQUENCE).
|
|
65
|
+
function ecdsaCoordSize(algorithm) {
|
|
66
|
+
switch (algorithm) {
|
|
67
|
+
case "ECDSA_SHA256":
|
|
68
|
+
return 32; // P-256
|
|
69
|
+
case "ECDSA_SHA384":
|
|
70
|
+
return 48; // P-384
|
|
71
|
+
case "ECDSA_SHA512":
|
|
72
|
+
return 66; // P-521
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Read a DER length field starting at der[offset]. Returns [length, bytesConsumed].
|
|
76
|
+
// Handles both short form (1 byte) and long form (0x81/0x82 prefix).
|
|
77
|
+
function readDerLength(der, offset) {
|
|
78
|
+
const first = der[offset];
|
|
79
|
+
if (first < 0x80) {
|
|
80
|
+
return [first, 1];
|
|
81
|
+
}
|
|
82
|
+
const numLenBytes = first & 0x7f;
|
|
83
|
+
let length = 0;
|
|
84
|
+
for (let i = 0; i < numLenBytes; i++) {
|
|
85
|
+
length = (length << 8) | der[offset + 1 + i];
|
|
86
|
+
}
|
|
87
|
+
return [length, 1 + numLenBytes];
|
|
88
|
+
}
|
|
89
|
+
// Convert a DER-encoded ECDSA signature (ASN.1 SEQUENCE { INTEGER r, INTEGER s })
|
|
90
|
+
// to IEEE P1363 format (r ∥ s, each zero-padded to coordSize bytes).
|
|
91
|
+
function derToP1363(der, coordSize) {
|
|
92
|
+
// DER structure: 0x30 <len> 0x02 <rLen> <r> 0x02 <sLen> <s>
|
|
93
|
+
// Skip the outer SEQUENCE tag (0x30) and its length (may be long-form for P-521).
|
|
94
|
+
let offset = 1; // skip 0x30
|
|
95
|
+
const [, seqLenBytes] = readDerLength(der, offset);
|
|
96
|
+
offset += seqLenBytes;
|
|
97
|
+
if (der[offset] !== 0x02) {
|
|
98
|
+
throw new Error("Invalid DER signature: expected INTEGER tag for r");
|
|
99
|
+
}
|
|
100
|
+
offset++; // skip 0x02 tag
|
|
101
|
+
const [rLen, rLenBytes] = readDerLength(der, offset);
|
|
102
|
+
offset += rLenBytes;
|
|
103
|
+
const r = der.slice(offset, offset + rLen);
|
|
104
|
+
offset += rLen;
|
|
105
|
+
if (der[offset] !== 0x02) {
|
|
106
|
+
throw new Error("Invalid DER signature: expected INTEGER tag for s");
|
|
107
|
+
}
|
|
108
|
+
offset++; // skip 0x02 tag
|
|
109
|
+
const [sLen, sLenBytes] = readDerLength(der, offset);
|
|
110
|
+
offset += sLenBytes;
|
|
111
|
+
const s = der.slice(offset, offset + sLen);
|
|
112
|
+
const result = new Uint8Array(new ArrayBuffer(coordSize * 2));
|
|
113
|
+
// r and s may have a leading 0x00 padding byte (DER positive integer) — strip it,
|
|
114
|
+
// then right-align into the fixed-size output.
|
|
115
|
+
const rStripped = r[0] === 0x00 ? r.slice(1) : r;
|
|
116
|
+
const sStripped = s[0] === 0x00 ? s.slice(1) : s;
|
|
117
|
+
result.set(rStripped, coordSize - rStripped.length);
|
|
118
|
+
result.set(sStripped, coordSize * 2 - sStripped.length);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
function pemToBytes(pem) {
|
|
122
|
+
const lines = pem.replace(/-----[A-Z ]+-----/g, "").replace(/\s+/g, "");
|
|
123
|
+
const binary = atob(lines);
|
|
124
|
+
const bytes = new Uint8Array(new ArrayBuffer(binary.length));
|
|
125
|
+
for (let i = 0; i < binary.length; i++) {
|
|
126
|
+
bytes[i] = binary.charCodeAt(i);
|
|
127
|
+
}
|
|
128
|
+
return bytes;
|
|
129
|
+
}
|
|
130
|
+
function signatureToBytes(signature, encoding) {
|
|
131
|
+
if (encoding === "base64") {
|
|
132
|
+
const binary = atob(signature);
|
|
133
|
+
const bytes = new Uint8Array(new ArrayBuffer(binary.length));
|
|
134
|
+
for (let i = 0; i < binary.length; i++) {
|
|
135
|
+
bytes[i] = binary.charCodeAt(i);
|
|
136
|
+
}
|
|
137
|
+
return bytes;
|
|
138
|
+
}
|
|
139
|
+
// hex
|
|
140
|
+
const bytes = new Uint8Array(new ArrayBuffer(signature.length / 2));
|
|
141
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
142
|
+
bytes[i] = parseInt(signature.slice(i * 2, i * 2 + 2), 16);
|
|
143
|
+
}
|
|
144
|
+
return bytes;
|
|
145
|
+
}
|
|
146
|
+
function getSubtleAlgorithms(algorithm) {
|
|
147
|
+
switch (algorithm) {
|
|
148
|
+
case "RSA_SHA256":
|
|
149
|
+
return {
|
|
150
|
+
importAlgorithm: { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
|
|
151
|
+
verifyAlgorithm: { name: "RSASSA-PKCS1-v1_5" },
|
|
152
|
+
};
|
|
153
|
+
case "RSA_SHA384":
|
|
154
|
+
return {
|
|
155
|
+
importAlgorithm: { name: "RSASSA-PKCS1-v1_5", hash: "SHA-384" },
|
|
156
|
+
verifyAlgorithm: { name: "RSASSA-PKCS1-v1_5" },
|
|
157
|
+
};
|
|
158
|
+
case "RSA_SHA512":
|
|
159
|
+
return {
|
|
160
|
+
importAlgorithm: { name: "RSASSA-PKCS1-v1_5", hash: "SHA-512" },
|
|
161
|
+
verifyAlgorithm: { name: "RSASSA-PKCS1-v1_5" },
|
|
162
|
+
};
|
|
163
|
+
case "ECDSA_SHA256":
|
|
164
|
+
return {
|
|
165
|
+
importAlgorithm: { name: "ECDSA", namedCurve: "P-256" },
|
|
166
|
+
verifyAlgorithm: { name: "ECDSA", hash: "SHA-256" },
|
|
167
|
+
};
|
|
168
|
+
case "ECDSA_SHA384":
|
|
169
|
+
return {
|
|
170
|
+
importAlgorithm: { name: "ECDSA", namedCurve: "P-384" },
|
|
171
|
+
verifyAlgorithm: { name: "ECDSA", hash: "SHA-384" },
|
|
172
|
+
};
|
|
173
|
+
case "ECDSA_SHA512":
|
|
174
|
+
return {
|
|
175
|
+
importAlgorithm: { name: "ECDSA", namedCurve: "P-521" },
|
|
176
|
+
verifyAlgorithm: { name: "ECDSA", hash: "SHA-512" },
|
|
177
|
+
};
|
|
178
|
+
case "ED25519":
|
|
179
|
+
return {
|
|
180
|
+
importAlgorithm: { name: "Ed25519" },
|
|
181
|
+
verifyAlgorithm: { name: "Ed25519" },
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function verifyAsymmetricSignature(args) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
if (index_js_1.RUNTIME.type === "node") {
|
|
188
|
+
const crypto = yield Promise.resolve().then(() => __importStar(require("crypto")));
|
|
189
|
+
if (args.algorithm === "ED25519") {
|
|
190
|
+
const signatureBytes = Uint8Array.from(Buffer.from(args.signature, args.encoding));
|
|
191
|
+
return crypto.verify(null, Uint8Array.from(Buffer.from(args.payload)), args.publicKey, signatureBytes);
|
|
192
|
+
}
|
|
193
|
+
const verifier = crypto.createVerify(getNodeAlgorithmName(args.algorithm));
|
|
194
|
+
verifier.update(args.payload);
|
|
195
|
+
return verifier.verify(args.publicKey, args.signature, args.encoding);
|
|
196
|
+
}
|
|
197
|
+
const subtle = globalThis.crypto.subtle;
|
|
198
|
+
const { importAlgorithm, verifyAlgorithm } = getSubtleAlgorithms(args.algorithm);
|
|
199
|
+
const keyBytes = pemToBytes(args.publicKey);
|
|
200
|
+
const key = yield subtle.importKey("spki", keyBytes, importAlgorithm, false, ["verify"]);
|
|
201
|
+
let signatureBytes = signatureToBytes(args.signature, args.encoding);
|
|
202
|
+
// Web Crypto requires IEEE P1363 format for ECDSA (raw r ∥ s), but the
|
|
203
|
+
// incoming signature is DER-encoded (the format Node and most libraries produce).
|
|
204
|
+
if (args.algorithm === "ECDSA_SHA256" || args.algorithm === "ECDSA_SHA384" || args.algorithm === "ECDSA_SHA512") {
|
|
205
|
+
signatureBytes = derToP1363(signatureBytes, ecdsaCoordSize(args.algorithm));
|
|
206
|
+
}
|
|
207
|
+
const payloadBytes = new TextEncoder().encode(args.payload);
|
|
208
|
+
return subtle.verify(verifyAlgorithm, key, signatureBytes, payloadBytes);
|
|
209
|
+
});
|
|
210
|
+
}
|
package/dist/cjs/index.d.ts
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
36
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.SuwardSDKTimeoutError = exports.SuwardSDKError = exports.SuwardSDKEnvironment = exports.SuwardSDKClient = exports.SuwardSDK = void 0;
|
|
39
|
+
exports.webhooks = exports.SuwardSDKTimeoutError = exports.SuwardSDKError = exports.SuwardSDKEnvironment = exports.SuwardSDKClient = exports.SuwardSDK = void 0;
|
|
40
40
|
exports.SuwardSDK = __importStar(require("./api/index.js"));
|
|
41
41
|
var Client_js_1 = require("./Client.js");
|
|
42
42
|
Object.defineProperty(exports, "SuwardSDKClient", { enumerable: true, get: function () { return Client_js_1.SuwardSDKClient; } });
|
|
@@ -46,3 +46,4 @@ var index_js_1 = require("./errors/index.js");
|
|
|
46
46
|
Object.defineProperty(exports, "SuwardSDKError", { enumerable: true, get: function () { return index_js_1.SuwardSDKError; } });
|
|
47
47
|
Object.defineProperty(exports, "SuwardSDKTimeoutError", { enumerable: true, get: function () { return index_js_1.SuwardSDKTimeoutError; } });
|
|
48
48
|
__exportStar(require("./exports.js"), exports);
|
|
49
|
+
exports.webhooks = __importStar(require("./webhooks/index.js"));
|
package/dist/cjs/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.0.
|
|
1
|
+
export declare const SDK_VERSION = "0.0.19";
|
package/dist/cjs/version.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify an asymmetric webhook signature.
|
|
3
|
+
*
|
|
4
|
+
* Extract the signature from the "X-Suward-Signature" header and pass it as the signatureHeader parameter.
|
|
5
|
+
* Extract the timestamp from the "X-Suward-Timestamp" header and pass it as the timestampHeader parameter.
|
|
6
|
+
*/
|
|
7
|
+
export declare class WebhooksHelper {
|
|
8
|
+
static verifySignature(requestBody: string, signatureHeader: string, publicKey: string, timestampHeader: string): Promise<boolean>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// This file was auto-generated by Fern from our API Definition.
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
39
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
40
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
41
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
42
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.WebhooksHelper = void 0;
|
|
47
|
+
const core = __importStar(require("../core/index.js"));
|
|
48
|
+
const TIMESTAMP_TOLERANCE_SECONDS = 300;
|
|
49
|
+
const SIGNATURE_PREFIX = "ed25519=";
|
|
50
|
+
/**
|
|
51
|
+
* Verify an asymmetric webhook signature.
|
|
52
|
+
*
|
|
53
|
+
* Extract the signature from the "X-Suward-Signature" header and pass it as the signatureHeader parameter.
|
|
54
|
+
* Extract the timestamp from the "X-Suward-Timestamp" header and pass it as the timestampHeader parameter.
|
|
55
|
+
*/
|
|
56
|
+
class WebhooksHelper {
|
|
57
|
+
static verifySignature(requestBody, signatureHeader, publicKey, timestampHeader) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
if (requestBody == null || signatureHeader == null || publicKey == null) {
|
|
60
|
+
throw new Error("Missing required parameters for webhook signature verification");
|
|
61
|
+
}
|
|
62
|
+
if (timestampHeader == null || timestampHeader === "") {
|
|
63
|
+
throw new Error("Missing timestamp header 'X-Suward-Timestamp' for webhook signature verification");
|
|
64
|
+
}
|
|
65
|
+
const timestampValue = parseInt(timestampHeader, 10);
|
|
66
|
+
if (Number.isNaN(timestampValue)) {
|
|
67
|
+
throw new Error("Invalid timestamp format: expected unix milliseconds");
|
|
68
|
+
}
|
|
69
|
+
const timestampMs = timestampValue;
|
|
70
|
+
if (Math.abs(Date.now() - timestampMs) > TIMESTAMP_TOLERANCE_SECONDS * 1000) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const sig = signatureHeader.startsWith(SIGNATURE_PREFIX)
|
|
74
|
+
? signatureHeader.slice(SIGNATURE_PREFIX.length)
|
|
75
|
+
: signatureHeader;
|
|
76
|
+
const payload = requestBody;
|
|
77
|
+
return yield core.verifyAsymmetricSignature({
|
|
78
|
+
payload: payload,
|
|
79
|
+
signature: sig,
|
|
80
|
+
publicKey: publicKey,
|
|
81
|
+
algorithm: "ED25519",
|
|
82
|
+
encoding: "hex",
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.WebhooksHelper = WebhooksHelper;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { WebhooksHelper } from "./WebhooksHelper.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebhooksHelper = void 0;
|
|
4
|
+
var WebhooksHelper_js_1 = require("./WebhooksHelper.js");
|
|
5
|
+
Object.defineProperty(exports, "WebhooksHelper", { enumerable: true, get: function () { return WebhooksHelper_js_1.WebhooksHelper; } });
|
package/dist/esm/BaseClient.mjs
CHANGED
|
@@ -6,8 +6,8 @@ export function normalizeClientOptions(options) {
|
|
|
6
6
|
const headers = mergeHeaders({
|
|
7
7
|
"X-Fern-Language": "JavaScript",
|
|
8
8
|
"X-Fern-SDK-Name": "pkg-sdk-test",
|
|
9
|
-
"X-Fern-SDK-Version": "0.0.
|
|
10
|
-
"User-Agent": "pkg-sdk-test/0.0.
|
|
9
|
+
"X-Fern-SDK-Version": "0.0.19",
|
|
10
|
+
"User-Agent": "pkg-sdk-test/0.0.19",
|
|
11
11
|
"X-Fern-Runtime": core.RUNTIME.type,
|
|
12
12
|
"X-Fern-Runtime-Version": core.RUNTIME.version,
|
|
13
13
|
}, options === null || options === void 0 ? void 0 : options.headers);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook body for a payment lifecycle transition. Signed over the raw body with the project's Ed25519 key; verify with project.webhookPublicKey. `createdAt` is the signed, trusted timestamp.
|
|
3
|
+
*/
|
|
4
|
+
export interface WebhookPaymentEvent {
|
|
5
|
+
type: WebhookPaymentEvent.Type;
|
|
6
|
+
eventId: string;
|
|
7
|
+
/** Event creation time, unix milliseconds. */
|
|
8
|
+
createdAt: number;
|
|
9
|
+
paymentId: string;
|
|
10
|
+
projectId: string;
|
|
11
|
+
externalId?: string | undefined;
|
|
12
|
+
status: string;
|
|
13
|
+
subStatus: string;
|
|
14
|
+
amount: string;
|
|
15
|
+
amountReceived: string;
|
|
16
|
+
amountConfirmed: string;
|
|
17
|
+
assetId?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare namespace WebhookPaymentEvent {
|
|
20
|
+
const Type: {
|
|
21
|
+
readonly PaymentAccepted: "payment.accepted";
|
|
22
|
+
readonly PaymentSuccess: "payment.success";
|
|
23
|
+
readonly PaymentFailed: "payment.failed";
|
|
24
|
+
};
|
|
25
|
+
type Type = (typeof Type)[keyof typeof Type];
|
|
26
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
export var WebhookPaymentEvent;
|
|
3
|
+
(function (WebhookPaymentEvent) {
|
|
4
|
+
WebhookPaymentEvent.Type = {
|
|
5
|
+
PaymentAccepted: "payment.accepted",
|
|
6
|
+
PaymentSuccess: "payment.success",
|
|
7
|
+
PaymentFailed: "payment.failed",
|
|
8
|
+
};
|
|
9
|
+
})(WebhookPaymentEvent || (WebhookPaymentEvent = {}));
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook body for a static-wallet deposit transition. Signed over the raw body with the project's Ed25519 key; verify with project.webhookPublicKey. `createdAt` is the signed, trusted timestamp.
|
|
3
|
+
*/
|
|
4
|
+
export interface WebhookStaticDepositEvent {
|
|
5
|
+
type: WebhookStaticDepositEvent.Type;
|
|
6
|
+
eventId: string;
|
|
7
|
+
/** Event creation time, unix milliseconds. */
|
|
8
|
+
createdAt: number;
|
|
9
|
+
staticWalletId: string;
|
|
10
|
+
depositId: string;
|
|
11
|
+
projectId: string;
|
|
12
|
+
externalId?: string | undefined;
|
|
13
|
+
address: string;
|
|
14
|
+
txHash: string;
|
|
15
|
+
transferIndex: string;
|
|
16
|
+
assetId: number;
|
|
17
|
+
amount: string;
|
|
18
|
+
netAmount: string;
|
|
19
|
+
fee: string;
|
|
20
|
+
networkFee: string;
|
|
21
|
+
status: string;
|
|
22
|
+
}
|
|
23
|
+
export declare namespace WebhookStaticDepositEvent {
|
|
24
|
+
const Type: {
|
|
25
|
+
readonly StaticDepositAccepted: "static_deposit.accepted";
|
|
26
|
+
readonly StaticDepositSuccess: "static_deposit.success";
|
|
27
|
+
};
|
|
28
|
+
type Type = (typeof Type)[keyof typeof Type];
|
|
29
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
export var WebhookStaticDepositEvent;
|
|
3
|
+
(function (WebhookStaticDepositEvent) {
|
|
4
|
+
WebhookStaticDepositEvent.Type = {
|
|
5
|
+
StaticDepositAccepted: "static_deposit.accepted",
|
|
6
|
+
StaticDepositSuccess: "static_deposit.success",
|
|
7
|
+
};
|
|
8
|
+
})(WebhookStaticDepositEvent || (WebhookStaticDepositEvent = {}));
|
|
@@ -12,3 +12,5 @@ export * from "./CryptopayRedirectConfigDto.mjs";
|
|
|
12
12
|
export * from "./CryptopayStaticDepositResponse.mjs";
|
|
13
13
|
export * from "./CryptopayStaticWalletResponse.mjs";
|
|
14
14
|
export * from "./CryptopayTransactionResponse.mjs";
|
|
15
|
+
export * from "./WebhookPaymentEvent.mjs";
|
|
16
|
+
export * from "./WebhookStaticDepositEvent.mjs";
|
|
@@ -12,3 +12,5 @@ export * from "./CryptopayRedirectConfigDto.mjs";
|
|
|
12
12
|
export * from "./CryptopayStaticDepositResponse.mjs";
|
|
13
13
|
export * from "./CryptopayStaticWalletResponse.mjs";
|
|
14
14
|
export * from "./CryptopayTransactionResponse.mjs";
|
|
15
|
+
export * from "./WebhookPaymentEvent.mjs";
|
|
16
|
+
export * from "./WebhookStaticDepositEvent.mjs";
|
package/dist/esm/core/index.mjs
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SignatureEncoding } from "./types.mjs";
|
|
2
|
+
export type HmacAlgorithm = "sha256" | "sha1" | "sha384" | "sha512";
|
|
3
|
+
export interface ComputeHmacSignatureArgs {
|
|
4
|
+
payload: string;
|
|
5
|
+
secret: string;
|
|
6
|
+
algorithm: HmacAlgorithm;
|
|
7
|
+
encoding: SignatureEncoding;
|
|
8
|
+
}
|
|
9
|
+
export declare function computeHmacSignature(args: ComputeHmacSignatureArgs): Promise<string>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { RUNTIME } from "../runtime/index.mjs";
|
|
11
|
+
function hmacAlgorithmToSubtleName(algorithm) {
|
|
12
|
+
switch (algorithm) {
|
|
13
|
+
case "sha1":
|
|
14
|
+
return "SHA-1";
|
|
15
|
+
case "sha256":
|
|
16
|
+
return "SHA-256";
|
|
17
|
+
case "sha384":
|
|
18
|
+
return "SHA-384";
|
|
19
|
+
case "sha512":
|
|
20
|
+
return "SHA-512";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function computeHmacSignature(args) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
if (RUNTIME.type === "node") {
|
|
26
|
+
const crypto = yield import("crypto");
|
|
27
|
+
const hmac = crypto.createHmac(args.algorithm, args.secret);
|
|
28
|
+
hmac.update(args.payload);
|
|
29
|
+
return hmac.digest(args.encoding);
|
|
30
|
+
}
|
|
31
|
+
const subtle = globalThis.crypto.subtle;
|
|
32
|
+
const enc = new TextEncoder();
|
|
33
|
+
const keyMaterial = yield subtle.importKey("raw", enc.encode(args.secret), { name: "HMAC", hash: hmacAlgorithmToSubtleName(args.algorithm) }, false, ["sign"]);
|
|
34
|
+
const signatureBuffer = yield subtle.sign("HMAC", keyMaterial, enc.encode(args.payload));
|
|
35
|
+
const bytes = new Uint8Array(signatureBuffer);
|
|
36
|
+
if (args.encoding === "hex") {
|
|
37
|
+
return Array.from(bytes)
|
|
38
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
39
|
+
.join("");
|
|
40
|
+
}
|
|
41
|
+
// base64
|
|
42
|
+
let binary = "";
|
|
43
|
+
for (const byte of bytes) {
|
|
44
|
+
binary += String.fromCharCode(byte);
|
|
45
|
+
}
|
|
46
|
+
return btoa(binary);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface FetchJwksArgs {
|
|
2
|
+
url: string;
|
|
3
|
+
keyId?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Fetches a public key from a JWKS endpoint and returns it as a PEM string.
|
|
7
|
+
*
|
|
8
|
+
* Only RSA keys (reconstructed from `n`/`e`) and keys with an `x5c` certificate chain are supported.
|
|
9
|
+
* EC (kty: "EC") and OKP (kty: "OKP") keys are **not** supported and will throw an error.
|
|
10
|
+
*
|
|
11
|
+
* @throws {Error} If the JWKS endpoint returns a non-OK response.
|
|
12
|
+
* @throws {Error} If no key matching `keyId` is found (after one cache-busting retry).
|
|
13
|
+
* @throws {Error} If the selected key has an unsupported type (e.g. EC or OKP).
|
|
14
|
+
*/
|
|
15
|
+
export declare function fetchJwks(args: FetchJwksArgs): Promise<string>;
|