litegate-sdk 1.0.0

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.
@@ -0,0 +1,23 @@
1
+ export declare class LiteGateClient {
2
+ private baseUrl;
3
+ constructor(baseUrl?: string);
4
+ initiateTelebirrPayment(title: string, amount: string, buyer_phone_number: string, publicKey: string, privateKey: string): Promise<any>;
5
+ telebirrCallback({ notify_url, appid, notify_time, merch_code, merch_order_id, payment_order_id, total_amount, trans_currency, trade_status, trans_end_time, callback_info, sign, sign_type, transId, }: {
6
+ notify_url: string;
7
+ appid: string;
8
+ notify_time: string;
9
+ merch_code: string;
10
+ merch_order_id: string;
11
+ payment_order_id: string;
12
+ total_amount: string;
13
+ trans_currency: string;
14
+ trade_status: string;
15
+ trans_end_time: string;
16
+ callback_info: string;
17
+ sign: string;
18
+ sign_type: string;
19
+ transId: string;
20
+ }): Promise<any>;
21
+ initiateCbebirrPayment(title: string, amount: string, buyer_phone_number: string, publicKey: string, privateKey: string): Promise<any>;
22
+ cbebirrCallback(EncVal: string, publicKey: string, privateKey: string): Promise<any>;
23
+ }
package/dist/client.js ADDED
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LiteGateClient = void 0;
4
+ const signature_1 = require("./crypto/signature");
5
+ class LiteGateClient {
6
+ constructor(baseUrl) {
7
+ this.baseUrl = baseUrl ?? "https://api.litegate.et";
8
+ }
9
+ async initiateTelebirrPayment(title, amount, buyer_phone_number, publicKey, privateKey) {
10
+ const body = { title, amount, buyer_phone_number };
11
+ const signature = await (0, signature_1.signRequest)(body, privateKey);
12
+ const response = await fetch(`${this.baseUrl}/v1/telebirr/initiate/`, {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json",
16
+ Authorization: `PublicKey ${publicKey}`,
17
+ "X-SIGNATURE": signature,
18
+ },
19
+ body: JSON.stringify(body),
20
+ });
21
+ if (!response.ok) {
22
+ const err = await response.json();
23
+ throw new Error(JSON.stringify(err));
24
+ }
25
+ return response.json();
26
+ }
27
+ async telebirrCallback({ notify_url, appid, notify_time, merch_code, merch_order_id, payment_order_id, total_amount, trans_currency, trade_status, trans_end_time, callback_info, sign, sign_type, transId, }) {
28
+ const body = {
29
+ notify_url,
30
+ appid,
31
+ notify_time,
32
+ merch_code,
33
+ merch_order_id,
34
+ payment_order_id,
35
+ total_amount,
36
+ trans_currency,
37
+ trade_status,
38
+ trans_end_time,
39
+ callback_info,
40
+ sign,
41
+ sign_type,
42
+ transId,
43
+ };
44
+ const response = await fetch(`${this.baseUrl}/v1/telebirr/notify/`, {
45
+ method: "POST",
46
+ headers: {
47
+ "Content-Type": "application/json",
48
+ },
49
+ body: JSON.stringify(body),
50
+ });
51
+ if (!response.ok) {
52
+ const err = await response.json();
53
+ throw new Error(JSON.stringify(err));
54
+ }
55
+ return response.json();
56
+ }
57
+ async initiateCbebirrPayment(title, amount, buyer_phone_number, publicKey, privateKey) {
58
+ const body = { title, amount, buyer_phone_number };
59
+ const signature = await (0, signature_1.signRequest)(body, privateKey);
60
+ const response = await fetch(`${this.baseUrl}/v1/cbebirr/initiate/`, {
61
+ method: "POST",
62
+ headers: {
63
+ "Content-Type": "application/json",
64
+ Authorization: `PublicKey ${publicKey}`,
65
+ "X-SIGNATURE": signature,
66
+ },
67
+ body: JSON.stringify(body),
68
+ });
69
+ if (!response.ok) {
70
+ const err = await response.json();
71
+ throw new Error(JSON.stringify(err));
72
+ }
73
+ return response.json();
74
+ }
75
+ async cbebirrCallback(EncVal, publicKey, privateKey) {
76
+ const body = { EncVal };
77
+ const signature = await (0, signature_1.signRequest)(body, privateKey);
78
+ const response = await fetch(`${this.baseUrl}/v1/cbebirr/notify/`, {
79
+ method: "POST",
80
+ headers: {
81
+ "Content-Type": "application/json",
82
+ Authorization: `PublicKey ${publicKey}`,
83
+ "X-SIGNATURE": signature,
84
+ },
85
+ body: JSON.stringify(body),
86
+ });
87
+ if (!response.ok) {
88
+ const err = await response.json();
89
+ throw new Error(JSON.stringify(err));
90
+ }
91
+ return response.json();
92
+ }
93
+ }
94
+ exports.LiteGateClient = LiteGateClient;
@@ -0,0 +1,10 @@
1
+ import type { ApiRequestOptions } from './ApiRequestOptions';
2
+ import type { ApiResult } from './ApiResult';
3
+ export declare class ApiError extends Error {
4
+ readonly url: string;
5
+ readonly status: number;
6
+ readonly statusText: string;
7
+ readonly body: any;
8
+ readonly request: ApiRequestOptions;
9
+ constructor(request: ApiRequestOptions, response: ApiResult, message: string);
10
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiError = void 0;
4
+ class ApiError extends Error {
5
+ constructor(request, response, message) {
6
+ super(message);
7
+ this.name = 'ApiError';
8
+ this.url = response.url;
9
+ this.status = response.status;
10
+ this.statusText = response.statusText;
11
+ this.body = response.body;
12
+ this.request = request;
13
+ }
14
+ }
15
+ exports.ApiError = ApiError;
@@ -0,0 +1,13 @@
1
+ export type ApiRequestOptions = {
2
+ readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
3
+ readonly url: string;
4
+ readonly path?: Record<string, any>;
5
+ readonly cookies?: Record<string, any>;
6
+ readonly headers?: Record<string, any>;
7
+ readonly query?: Record<string, any>;
8
+ readonly formData?: Record<string, any>;
9
+ readonly body?: any;
10
+ readonly mediaType?: string;
11
+ readonly responseHeader?: string;
12
+ readonly errors?: Record<number, string>;
13
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export type ApiResult = {
2
+ readonly url: string;
3
+ readonly ok: boolean;
4
+ readonly status: number;
5
+ readonly statusText: string;
6
+ readonly body: any;
7
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ export declare class CancelError extends Error {
2
+ constructor(message: string);
3
+ get isCancelled(): boolean;
4
+ }
5
+ export interface OnCancel {
6
+ readonly isResolved: boolean;
7
+ readonly isRejected: boolean;
8
+ readonly isCancelled: boolean;
9
+ (cancelHandler: () => void): void;
10
+ }
11
+ export declare class CancelablePromise<T> implements Promise<T> {
12
+ #private;
13
+ constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void, onCancel: OnCancel) => void);
14
+ get [Symbol.toStringTag](): string;
15
+ then<TResult1 = T, TResult2 = never>(onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
16
+ catch<TResult = never>(onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
17
+ finally(onFinally?: (() => void) | null): Promise<T>;
18
+ cancel(): void;
19
+ get isCancelled(): boolean;
20
+ }
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _CancelablePromise_isResolved, _CancelablePromise_isRejected, _CancelablePromise_isCancelled, _CancelablePromise_cancelHandlers, _CancelablePromise_promise, _CancelablePromise_resolve, _CancelablePromise_reject;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CancelablePromise = exports.CancelError = void 0;
16
+ /* generated using openapi-typescript-codegen -- do not edit */
17
+ /* istanbul ignore file */
18
+ /* tslint:disable */
19
+ /* eslint-disable */
20
+ class CancelError extends Error {
21
+ constructor(message) {
22
+ super(message);
23
+ this.name = 'CancelError';
24
+ }
25
+ get isCancelled() {
26
+ return true;
27
+ }
28
+ }
29
+ exports.CancelError = CancelError;
30
+ class CancelablePromise {
31
+ constructor(executor) {
32
+ _CancelablePromise_isResolved.set(this, void 0);
33
+ _CancelablePromise_isRejected.set(this, void 0);
34
+ _CancelablePromise_isCancelled.set(this, void 0);
35
+ _CancelablePromise_cancelHandlers.set(this, void 0);
36
+ _CancelablePromise_promise.set(this, void 0);
37
+ _CancelablePromise_resolve.set(this, void 0);
38
+ _CancelablePromise_reject.set(this, void 0);
39
+ __classPrivateFieldSet(this, _CancelablePromise_isResolved, false, "f");
40
+ __classPrivateFieldSet(this, _CancelablePromise_isRejected, false, "f");
41
+ __classPrivateFieldSet(this, _CancelablePromise_isCancelled, false, "f");
42
+ __classPrivateFieldSet(this, _CancelablePromise_cancelHandlers, [], "f");
43
+ __classPrivateFieldSet(this, _CancelablePromise_promise, new Promise((resolve, reject) => {
44
+ __classPrivateFieldSet(this, _CancelablePromise_resolve, resolve, "f");
45
+ __classPrivateFieldSet(this, _CancelablePromise_reject, reject, "f");
46
+ const onResolve = (value) => {
47
+ if (__classPrivateFieldGet(this, _CancelablePromise_isResolved, "f") || __classPrivateFieldGet(this, _CancelablePromise_isRejected, "f") || __classPrivateFieldGet(this, _CancelablePromise_isCancelled, "f")) {
48
+ return;
49
+ }
50
+ __classPrivateFieldSet(this, _CancelablePromise_isResolved, true, "f");
51
+ if (__classPrivateFieldGet(this, _CancelablePromise_resolve, "f"))
52
+ __classPrivateFieldGet(this, _CancelablePromise_resolve, "f").call(this, value);
53
+ };
54
+ const onReject = (reason) => {
55
+ if (__classPrivateFieldGet(this, _CancelablePromise_isResolved, "f") || __classPrivateFieldGet(this, _CancelablePromise_isRejected, "f") || __classPrivateFieldGet(this, _CancelablePromise_isCancelled, "f")) {
56
+ return;
57
+ }
58
+ __classPrivateFieldSet(this, _CancelablePromise_isRejected, true, "f");
59
+ if (__classPrivateFieldGet(this, _CancelablePromise_reject, "f"))
60
+ __classPrivateFieldGet(this, _CancelablePromise_reject, "f").call(this, reason);
61
+ };
62
+ const onCancel = (cancelHandler) => {
63
+ if (__classPrivateFieldGet(this, _CancelablePromise_isResolved, "f") || __classPrivateFieldGet(this, _CancelablePromise_isRejected, "f") || __classPrivateFieldGet(this, _CancelablePromise_isCancelled, "f")) {
64
+ return;
65
+ }
66
+ __classPrivateFieldGet(this, _CancelablePromise_cancelHandlers, "f").push(cancelHandler);
67
+ };
68
+ Object.defineProperty(onCancel, 'isResolved', {
69
+ get: () => __classPrivateFieldGet(this, _CancelablePromise_isResolved, "f"),
70
+ });
71
+ Object.defineProperty(onCancel, 'isRejected', {
72
+ get: () => __classPrivateFieldGet(this, _CancelablePromise_isRejected, "f"),
73
+ });
74
+ Object.defineProperty(onCancel, 'isCancelled', {
75
+ get: () => __classPrivateFieldGet(this, _CancelablePromise_isCancelled, "f"),
76
+ });
77
+ return executor(onResolve, onReject, onCancel);
78
+ }), "f");
79
+ }
80
+ get [(_CancelablePromise_isResolved = new WeakMap(), _CancelablePromise_isRejected = new WeakMap(), _CancelablePromise_isCancelled = new WeakMap(), _CancelablePromise_cancelHandlers = new WeakMap(), _CancelablePromise_promise = new WeakMap(), _CancelablePromise_resolve = new WeakMap(), _CancelablePromise_reject = new WeakMap(), Symbol.toStringTag)]() {
81
+ return "Cancellable Promise";
82
+ }
83
+ then(onFulfilled, onRejected) {
84
+ return __classPrivateFieldGet(this, _CancelablePromise_promise, "f").then(onFulfilled, onRejected);
85
+ }
86
+ catch(onRejected) {
87
+ return __classPrivateFieldGet(this, _CancelablePromise_promise, "f").catch(onRejected);
88
+ }
89
+ finally(onFinally) {
90
+ return __classPrivateFieldGet(this, _CancelablePromise_promise, "f").finally(onFinally);
91
+ }
92
+ cancel() {
93
+ if (__classPrivateFieldGet(this, _CancelablePromise_isResolved, "f") || __classPrivateFieldGet(this, _CancelablePromise_isRejected, "f") || __classPrivateFieldGet(this, _CancelablePromise_isCancelled, "f")) {
94
+ return;
95
+ }
96
+ __classPrivateFieldSet(this, _CancelablePromise_isCancelled, true, "f");
97
+ if (__classPrivateFieldGet(this, _CancelablePromise_cancelHandlers, "f").length) {
98
+ try {
99
+ for (const cancelHandler of __classPrivateFieldGet(this, _CancelablePromise_cancelHandlers, "f")) {
100
+ cancelHandler();
101
+ }
102
+ }
103
+ catch (error) {
104
+ console.warn('Cancellation threw an error', error);
105
+ return;
106
+ }
107
+ }
108
+ __classPrivateFieldGet(this, _CancelablePromise_cancelHandlers, "f").length = 0;
109
+ if (__classPrivateFieldGet(this, _CancelablePromise_reject, "f"))
110
+ __classPrivateFieldGet(this, _CancelablePromise_reject, "f").call(this, new CancelError('Request aborted'));
111
+ }
112
+ get isCancelled() {
113
+ return __classPrivateFieldGet(this, _CancelablePromise_isCancelled, "f");
114
+ }
115
+ }
116
+ exports.CancelablePromise = CancelablePromise;
@@ -0,0 +1,16 @@
1
+ import type { ApiRequestOptions } from './ApiRequestOptions';
2
+ type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
3
+ type Headers = Record<string, string>;
4
+ export type OpenAPIConfig = {
5
+ BASE: string;
6
+ VERSION: string;
7
+ WITH_CREDENTIALS: boolean;
8
+ CREDENTIALS: 'include' | 'omit' | 'same-origin';
9
+ TOKEN?: string | Resolver<string> | undefined;
10
+ USERNAME?: string | Resolver<string> | undefined;
11
+ PASSWORD?: string | Resolver<string> | undefined;
12
+ HEADERS?: Headers | Resolver<Headers> | undefined;
13
+ ENCODE_PATH?: ((path: string) => string) | undefined;
14
+ };
15
+ export declare const OpenAPI: OpenAPIConfig;
16
+ export {};
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenAPI = void 0;
4
+ exports.OpenAPI = {
5
+ BASE: 'https://api.litegate.et',
6
+ VERSION: '1.0.0',
7
+ WITH_CREDENTIALS: false,
8
+ CREDENTIALS: 'include',
9
+ TOKEN: undefined,
10
+ USERNAME: undefined,
11
+ PASSWORD: undefined,
12
+ HEADERS: undefined,
13
+ ENCODE_PATH: undefined,
14
+ };
@@ -0,0 +1,34 @@
1
+ import type { AxiosResponse, AxiosInstance } from "axios";
2
+ import FormData from "form-data";
3
+ import type { ApiRequestOptions } from "./ApiRequestOptions";
4
+ import type { ApiResult } from "./ApiResult";
5
+ import { CancelablePromise } from "./CancelablePromise";
6
+ import type { OnCancel } from "./CancelablePromise";
7
+ import type { OpenAPIConfig } from "./OpenAPI";
8
+ export declare const isDefined: <T>(value: T | null | undefined) => value is Exclude<T, null | undefined>;
9
+ export declare const isString: (value: any) => value is string;
10
+ export declare const isStringWithValue: (value: any) => value is string;
11
+ export declare const isBlob: (value: any) => value is Blob;
12
+ export declare const isFormData: (value: any) => value is FormData;
13
+ export declare const isSuccess: (status: number) => boolean;
14
+ export declare const base64: (str: string) => string;
15
+ export declare const getQueryString: (params: Record<string, any>) => string;
16
+ export declare const getFormData: (options: ApiRequestOptions) => FormData | undefined;
17
+ type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
18
+ export declare const resolve: <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>) => Promise<T | undefined>;
19
+ export declare const getHeaders: (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData) => Promise<Record<string, string>>;
20
+ export declare const getRequestBody: (options: ApiRequestOptions) => any;
21
+ export declare const sendRequest: <T>(config: OpenAPIConfig, options: ApiRequestOptions, url: string, body: any, formData: FormData | undefined, headers: Record<string, string>, onCancel: OnCancel, axiosClient: AxiosInstance) => Promise<AxiosResponse<T>>;
22
+ export declare const getResponseHeader: (response: AxiosResponse<any>, responseHeader?: string) => string | undefined;
23
+ export declare const getResponseBody: (response: AxiosResponse<any>) => any;
24
+ export declare const catchErrorCodes: (options: ApiRequestOptions, result: ApiResult) => void;
25
+ /**
26
+ * Request method
27
+ * @param config The OpenAPI configuration object
28
+ * @param options The request options from the service
29
+ * @param axiosClient The axios client instance to use
30
+ * @returns CancelablePromise<T>
31
+ * @throws ApiError
32
+ */
33
+ export declare const request: <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient?: AxiosInstance) => CancelablePromise<T>;
34
+ export {};
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.request = exports.catchErrorCodes = exports.getResponseBody = exports.getResponseHeader = exports.sendRequest = exports.getRequestBody = exports.getHeaders = exports.resolve = exports.getFormData = exports.getQueryString = exports.base64 = exports.isSuccess = exports.isFormData = exports.isBlob = exports.isStringWithValue = exports.isString = exports.isDefined = void 0;
7
+ /* generated using openapi-typescript-codegen -- do not edit */
8
+ /* istanbul ignore file */
9
+ /* tslint:disable */
10
+ /* eslint-disable */
11
+ const axios_1 = __importDefault(require("axios"));
12
+ const form_data_1 = __importDefault(require("form-data"));
13
+ const ApiError_1 = require("./ApiError");
14
+ const CancelablePromise_1 = require("./CancelablePromise");
15
+ const isDefined = (value) => {
16
+ return value !== undefined && value !== null;
17
+ };
18
+ exports.isDefined = isDefined;
19
+ const isString = (value) => {
20
+ return typeof value === "string";
21
+ };
22
+ exports.isString = isString;
23
+ const isStringWithValue = (value) => {
24
+ return (0, exports.isString)(value) && value !== "";
25
+ };
26
+ exports.isStringWithValue = isStringWithValue;
27
+ const isBlob = (value) => {
28
+ return (typeof value === "object" &&
29
+ typeof value.type === "string" &&
30
+ typeof value.stream === "function" &&
31
+ typeof value.arrayBuffer === "function" &&
32
+ typeof value.constructor === "function" &&
33
+ typeof value.constructor.name === "string" &&
34
+ /^(Blob|File)$/.test(value.constructor.name) &&
35
+ /^(Blob|File)$/.test(value[Symbol.toStringTag]));
36
+ };
37
+ exports.isBlob = isBlob;
38
+ const isFormData = (value) => {
39
+ return value instanceof form_data_1.default;
40
+ };
41
+ exports.isFormData = isFormData;
42
+ const isSuccess = (status) => {
43
+ return status >= 200 && status < 300;
44
+ };
45
+ exports.isSuccess = isSuccess;
46
+ const base64 = (str) => {
47
+ try {
48
+ return btoa(str);
49
+ }
50
+ catch (err) {
51
+ // @ts-ignore
52
+ return Buffer.from(str).toString("base64");
53
+ }
54
+ };
55
+ exports.base64 = base64;
56
+ const getQueryString = (params) => {
57
+ const qs = [];
58
+ const append = (key, value) => {
59
+ qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
60
+ };
61
+ const process = (key, value) => {
62
+ if ((0, exports.isDefined)(value)) {
63
+ if (Array.isArray(value)) {
64
+ value.forEach((v) => {
65
+ process(key, v);
66
+ });
67
+ }
68
+ else if (typeof value === "object") {
69
+ Object.entries(value).forEach(([k, v]) => {
70
+ process(`${key}[${k}]`, v);
71
+ });
72
+ }
73
+ else {
74
+ append(key, value);
75
+ }
76
+ }
77
+ };
78
+ Object.entries(params).forEach(([key, value]) => {
79
+ process(key, value);
80
+ });
81
+ if (qs.length > 0) {
82
+ return `?${qs.join("&")}`;
83
+ }
84
+ return "";
85
+ };
86
+ exports.getQueryString = getQueryString;
87
+ const getUrl = (config, options) => {
88
+ const encoder = config.ENCODE_PATH || encodeURI;
89
+ const path = options.url
90
+ .replace("{api-version}", config.VERSION)
91
+ .replace(/{(.*?)}/g, (substring, group) => {
92
+ if (options.path?.hasOwnProperty(group)) {
93
+ return encoder(String(options.path[group]));
94
+ }
95
+ return substring;
96
+ });
97
+ const url = `${config.BASE}${path}`;
98
+ if (options.query) {
99
+ return `${url}${(0, exports.getQueryString)(options.query)}`;
100
+ }
101
+ return url;
102
+ };
103
+ const getFormData = (options) => {
104
+ if (options.formData) {
105
+ const formData = new form_data_1.default();
106
+ const process = (key, value) => {
107
+ if ((0, exports.isString)(value) || (0, exports.isBlob)(value)) {
108
+ formData.append(key, value);
109
+ }
110
+ else {
111
+ formData.append(key, JSON.stringify(value));
112
+ }
113
+ };
114
+ Object.entries(options.formData)
115
+ .filter(([_, value]) => (0, exports.isDefined)(value))
116
+ .forEach(([key, value]) => {
117
+ if (Array.isArray(value)) {
118
+ value.forEach((v) => process(key, v));
119
+ }
120
+ else {
121
+ process(key, value);
122
+ }
123
+ });
124
+ return formData;
125
+ }
126
+ return undefined;
127
+ };
128
+ exports.getFormData = getFormData;
129
+ const resolve = async (options, resolver) => {
130
+ if (typeof resolver === "function") {
131
+ return resolver(options);
132
+ }
133
+ return resolver;
134
+ };
135
+ exports.resolve = resolve;
136
+ const getHeaders = async (config, options, formData) => {
137
+ const [token, username, password, additionalHeaders] = await Promise.all([
138
+ (0, exports.resolve)(options, config.TOKEN),
139
+ (0, exports.resolve)(options, config.USERNAME),
140
+ (0, exports.resolve)(options, config.PASSWORD),
141
+ (0, exports.resolve)(options, config.HEADERS),
142
+ ]);
143
+ const formHeaders = (typeof formData?.getHeaders === "function" && formData?.getHeaders()) ||
144
+ {};
145
+ const headers = Object.entries({
146
+ Accept: "application/json",
147
+ ...additionalHeaders,
148
+ ...options.headers,
149
+ ...formHeaders,
150
+ })
151
+ .filter(([_, value]) => (0, exports.isDefined)(value))
152
+ .reduce((headers, [key, value]) => ({
153
+ ...headers,
154
+ [key]: String(value),
155
+ }), {});
156
+ if ((0, exports.isStringWithValue)(token)) {
157
+ headers["Authorization"] = `PublicKey ${token}`;
158
+ }
159
+ if ((0, exports.isStringWithValue)(username) && (0, exports.isStringWithValue)(password)) {
160
+ const credentials = (0, exports.base64)(`${username}:${password}`);
161
+ headers["Authorization"] = `Basic ${credentials}`;
162
+ }
163
+ if (options.body !== undefined) {
164
+ if (options.mediaType) {
165
+ headers["Content-Type"] = options.mediaType;
166
+ }
167
+ else if ((0, exports.isBlob)(options.body)) {
168
+ headers["Content-Type"] = options.body.type || "application/octet-stream";
169
+ }
170
+ else if ((0, exports.isString)(options.body)) {
171
+ headers["Content-Type"] = "text/plain";
172
+ }
173
+ else if (!(0, exports.isFormData)(options.body)) {
174
+ headers["Content-Type"] = "application/json";
175
+ }
176
+ }
177
+ return headers;
178
+ };
179
+ exports.getHeaders = getHeaders;
180
+ const getRequestBody = (options) => {
181
+ if (options.body) {
182
+ return options.body;
183
+ }
184
+ return undefined;
185
+ };
186
+ exports.getRequestBody = getRequestBody;
187
+ const sendRequest = async (config, options, url, body, formData, headers, onCancel, axiosClient) => {
188
+ const source = axios_1.default.CancelToken.source();
189
+ const requestConfig = {
190
+ url,
191
+ headers,
192
+ data: body ?? formData,
193
+ method: options.method,
194
+ withCredentials: config.WITH_CREDENTIALS,
195
+ withXSRFToken: config.CREDENTIALS === "include" ? config.WITH_CREDENTIALS : false,
196
+ cancelToken: source.token,
197
+ };
198
+ onCancel(() => source.cancel("The user aborted a request."));
199
+ try {
200
+ return await axiosClient.request(requestConfig);
201
+ }
202
+ catch (error) {
203
+ const axiosError = error;
204
+ if (axiosError.response) {
205
+ return axiosError.response;
206
+ }
207
+ throw error;
208
+ }
209
+ };
210
+ exports.sendRequest = sendRequest;
211
+ const getResponseHeader = (response, responseHeader) => {
212
+ if (responseHeader) {
213
+ const content = response.headers[responseHeader];
214
+ if ((0, exports.isString)(content)) {
215
+ return content;
216
+ }
217
+ }
218
+ return undefined;
219
+ };
220
+ exports.getResponseHeader = getResponseHeader;
221
+ const getResponseBody = (response) => {
222
+ if (response.status !== 204) {
223
+ return response.data;
224
+ }
225
+ return undefined;
226
+ };
227
+ exports.getResponseBody = getResponseBody;
228
+ const catchErrorCodes = (options, result) => {
229
+ const errors = {
230
+ 400: "Bad Request",
231
+ 401: "Unauthorized",
232
+ 403: "Forbidden",
233
+ 404: "Not Found",
234
+ 500: "Internal Server Error",
235
+ 502: "Bad Gateway",
236
+ 503: "Service Unavailable",
237
+ ...options.errors,
238
+ };
239
+ const error = errors[result.status];
240
+ if (error) {
241
+ throw new ApiError_1.ApiError(options, result, error);
242
+ }
243
+ if (!result.ok) {
244
+ const errorStatus = result.status ?? "unknown";
245
+ const errorStatusText = result.statusText ?? "unknown";
246
+ const errorBody = (() => {
247
+ try {
248
+ return JSON.stringify(result.body, null, 2);
249
+ }
250
+ catch (e) {
251
+ return undefined;
252
+ }
253
+ })();
254
+ throw new ApiError_1.ApiError(options, result, `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`);
255
+ }
256
+ };
257
+ exports.catchErrorCodes = catchErrorCodes;
258
+ /**
259
+ * Request method
260
+ * @param config The OpenAPI configuration object
261
+ * @param options The request options from the service
262
+ * @param axiosClient The axios client instance to use
263
+ * @returns CancelablePromise<T>
264
+ * @throws ApiError
265
+ */
266
+ const request = (config, options, axiosClient = axios_1.default) => {
267
+ return new CancelablePromise_1.CancelablePromise(async (resolve, reject, onCancel) => {
268
+ try {
269
+ const url = getUrl(config, options);
270
+ const formData = (0, exports.getFormData)(options);
271
+ const body = (0, exports.getRequestBody)(options);
272
+ const headers = await (0, exports.getHeaders)(config, options, formData);
273
+ if (!onCancel.isCancelled) {
274
+ const response = await (0, exports.sendRequest)(config, options, url, body, formData, headers, onCancel, axiosClient);
275
+ const responseBody = (0, exports.getResponseBody)(response);
276
+ const responseHeader = (0, exports.getResponseHeader)(response, options.responseHeader);
277
+ const result = {
278
+ url,
279
+ ok: (0, exports.isSuccess)(response.status),
280
+ status: response.status,
281
+ statusText: response.statusText,
282
+ body: responseHeader ?? responseBody,
283
+ };
284
+ (0, exports.catchErrorCodes)(options, result);
285
+ resolve(result.body);
286
+ }
287
+ }
288
+ catch (error) {
289
+ reject(error);
290
+ }
291
+ });
292
+ };
293
+ exports.request = request;
@@ -0,0 +1,2 @@
1
+ export declare function canonicalJson(data: Record<string, unknown>): string;
2
+ export declare function signRequest(data: Record<string, unknown>, pkcs8: string): Promise<string>;
@@ -0,0 +1,80 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.canonicalJson = canonicalJson;
37
+ exports.signRequest = signRequest;
38
+ const forge = __importStar(require("node-forge"));
39
+ function canonicalJson(data) {
40
+ const sorted = Object.keys(data)
41
+ .sort()
42
+ .reduce((acc, key) => {
43
+ acc[key] = data[key];
44
+ return acc;
45
+ }, {});
46
+ return JSON.stringify(sorted);
47
+ }
48
+ // Clean the PEM (handle both literal \n and real newlines)
49
+ function cleanPem(pem) {
50
+ return pem
51
+ .replace(/\\n/g, "\n") // Convert literal \n to newlines if present
52
+ .replace(/\r\n/g, "\n") // Normalize Windows line endings
53
+ .trim(); // Remove extra whitespace
54
+ }
55
+ function parsePrivateKey(pem) {
56
+ // Remove headers/footers and whitespace
57
+ const b64 = pem
58
+ .replace("-----BEGIN PRIVATE KEY-----", "")
59
+ .replace("-----END PRIVATE KEY-----", "")
60
+ .replace(/\s/g, ""); // Remove ALL whitespace including newlines
61
+ const der = forge.util.decode64(b64);
62
+ const asn1 = forge.asn1.fromDer(der);
63
+ // Try to parse as generic private key info (PKCS#8)
64
+ return forge.pki.privateKeyFromAsn1(asn1);
65
+ }
66
+ async function signRequest(data, pkcs8) {
67
+ const cleanedPem = cleanPem(pkcs8);
68
+ const privateKey = parsePrivateKey(cleanedPem);
69
+ const md = forge.md.sha256.create();
70
+ md.update(canonicalJson(data), "utf8");
71
+ // Forge uses a different PSS API
72
+ const pss = forge.pss.create({
73
+ md: forge.md.sha256.create(),
74
+ mgf: forge.mgf.mgf1.create(forge.md.sha256.create()),
75
+ saltLength: 32, // or calculate max length based on key size
76
+ });
77
+ const signature = privateKey.sign(md, pss);
78
+ const signatureB64 = forge.util.encode64(signature);
79
+ return signatureB64;
80
+ }
@@ -0,0 +1,8 @@
1
+ export { ApiError } from "./core/ApiError";
2
+ export { CancelablePromise, CancelError } from "./core/CancelablePromise";
3
+ export { OpenAPI } from "./core/OpenAPI";
4
+ export type { OpenAPIConfig } from "./core/OpenAPI";
5
+ export type { ErrorResponse } from "./models/ErrorResponse";
6
+ export type { SuccessResponse } from "./models/SuccessResponse";
7
+ export type { TelebirrPaymentRequest } from "./models/TelebirrPaymentRequest";
8
+ export { TelebirrService } from "./services/TelebirrService";
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelebirrService = exports.OpenAPI = exports.CancelError = exports.CancelablePromise = exports.ApiError = void 0;
4
+ var ApiError_1 = require("./core/ApiError");
5
+ Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return ApiError_1.ApiError; } });
6
+ var CancelablePromise_1 = require("./core/CancelablePromise");
7
+ Object.defineProperty(exports, "CancelablePromise", { enumerable: true, get: function () { return CancelablePromise_1.CancelablePromise; } });
8
+ Object.defineProperty(exports, "CancelError", { enumerable: true, get: function () { return CancelablePromise_1.CancelError; } });
9
+ var OpenAPI_1 = require("./core/OpenAPI");
10
+ Object.defineProperty(exports, "OpenAPI", { enumerable: true, get: function () { return OpenAPI_1.OpenAPI; } });
11
+ var TelebirrService_1 = require("./services/TelebirrService");
12
+ Object.defineProperty(exports, "TelebirrService", { enumerable: true, get: function () { return TelebirrService_1.TelebirrService; } });
@@ -0,0 +1,3 @@
1
+ export type ErrorResponse = {
2
+ error?: string;
3
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export type SuccessResponse = {
2
+ status?: string;
3
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ export type TelebirrPaymentRequest = {
2
+ /**
3
+ * Payment title or description
4
+ */
5
+ title: string;
6
+ /**
7
+ * Payment amount as a string (to preserve formatting).
8
+ *
9
+ */
10
+ amount: string;
11
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,30 @@
1
+ import type { SuccessResponse } from '../models/SuccessResponse';
2
+ import type { TelebirrPaymentRequest } from '../models/TelebirrPaymentRequest';
3
+ import type { CancelablePromise } from '../core/CancelablePromise';
4
+ export declare class TelebirrService {
5
+ /**
6
+ * Initiate Telebirr payment
7
+ * Initiates a Telebirr payment request.
8
+ *
9
+ * ### Signature rules
10
+ * - Canonical JSON:
11
+ * - Keys sorted alphabetically
12
+ * - No spaces
13
+ * - Algorithm: RSA-PKCS1v1.5 + SHA-256
14
+ * - Signature must be Base64 encoded
15
+ *
16
+ * @param authorization Client public key (base64, without PEM headers).
17
+ *
18
+ * Format:
19
+ * ```
20
+ * PublicKey MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
21
+ * ```
22
+ *
23
+ * @param xSignature Base64-encoded RSA-SHA256 signature of the canonical JSON request body.
24
+ *
25
+ * @param requestBody
26
+ * @returns SuccessResponse Signature valid, payment request accepted
27
+ * @throws ApiError
28
+ */
29
+ static telebirrInitiatePayment(authorization: string, xSignature: string, requestBody: TelebirrPaymentRequest): CancelablePromise<SuccessResponse>;
30
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelebirrService = void 0;
4
+ const OpenAPI_1 = require("../core/OpenAPI");
5
+ const request_1 = require("../core/request");
6
+ class TelebirrService {
7
+ /**
8
+ * Initiate Telebirr payment
9
+ * Initiates a Telebirr payment request.
10
+ *
11
+ * ### Signature rules
12
+ * - Canonical JSON:
13
+ * - Keys sorted alphabetically
14
+ * - No spaces
15
+ * - Algorithm: RSA-PKCS1v1.5 + SHA-256
16
+ * - Signature must be Base64 encoded
17
+ *
18
+ * @param authorization Client public key (base64, without PEM headers).
19
+ *
20
+ * Format:
21
+ * ```
22
+ * PublicKey MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
23
+ * ```
24
+ *
25
+ * @param xSignature Base64-encoded RSA-SHA256 signature of the canonical JSON request body.
26
+ *
27
+ * @param requestBody
28
+ * @returns SuccessResponse Signature valid, payment request accepted
29
+ * @throws ApiError
30
+ */
31
+ static telebirrInitiatePayment(authorization, xSignature, requestBody) {
32
+ return (0, request_1.request)(OpenAPI_1.OpenAPI, {
33
+ method: 'POST',
34
+ url: '/v1/telebirr/initiate-payment',
35
+ headers: {
36
+ 'Authorization': authorization,
37
+ 'X-SIGNATURE': xSignature,
38
+ },
39
+ body: requestBody,
40
+ mediaType: 'application/json',
41
+ errors: {
42
+ 400: `Invalid request body`,
43
+ 401: `Invalid or missing signature / public key`,
44
+ 403: `Telebirr service not enabled for user`,
45
+ },
46
+ });
47
+ }
48
+ }
49
+ exports.TelebirrService = TelebirrService;
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "litegate-sdk",
3
+ "version": "1.0.0",
4
+ "description": "Official TypeScript SDK for LiteGate API",
5
+ "main": "index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "build": "tsc",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [],
16
+ "author": "",
17
+ "license": "ISC",
18
+ "type": "commonjs",
19
+ "dependencies": {
20
+ "@types/node-forge": "^1.3.14",
21
+ "axios": "^1.13.2",
22
+ "crypto": "^1.0.1",
23
+ "jose": "^6.1.3",
24
+ "node-forge": "^1.3.3",
25
+ "openapi-typescript": "^7.10.1"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^25.1.0",
29
+ "typescript": "^5.9.3"
30
+ }
31
+ }