@tineon/t9n 0.1.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.
@@ -0,0 +1,159 @@
1
+ import { z } from "zod";
2
+ export declare const NATIVE_CURRENCIES: readonly ["BTC", "ETH", "BNB", "MATIC", "AVAX", "SOL", "TRX", "LSK", "FLOW", "RON", "SEI", "FTM", "HBAR"];
3
+ export type NativeCurrency = (typeof NATIVE_CURRENCIES)[number];
4
+ export type SupportedCurrency = NativeCurrency;
5
+ export type T9nButtonTheme = "solid" | "light" | "outline";
6
+ export type T9nButtonOptions = {
7
+ text?: string;
8
+ className?: string;
9
+ theme?: T9nButtonTheme;
10
+ style?: Record<string, string>;
11
+ };
12
+ export type T9nCheckoutStatus = "created" | "awaiting_payment" | "pending_confirmation" | "expired" | "settled" | "failed" | "closed";
13
+ export type T9nHooks = {
14
+ onOpen?: () => void;
15
+ onClose?: () => void;
16
+ onSessionCreated?: (session: {
17
+ sessionId: string;
18
+ expiresAt: string;
19
+ }) => void;
20
+ onCurrencySelected?: (payload: {
21
+ currency: string;
22
+ network: string;
23
+ depositAddress: string;
24
+ expectedAmountCrypto: string;
25
+ }) => void;
26
+ onStatusChange?: (status: T9nCheckoutStatus) => void;
27
+ onSuccess?: (payload: {
28
+ sessionId: string;
29
+ status: string;
30
+ }) => void;
31
+ onFail?: (payload: {
32
+ sessionId?: string;
33
+ error: string;
34
+ }) => void;
35
+ };
36
+ export declare const T9N_DEFAULT_API_BASE_URL = "https://slimepay.com";
37
+ export declare const checkoutConfigSchema: z.ZodObject<{
38
+ publicKey: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>;
39
+ amountNgn: z.ZodNumber;
40
+ currencies: z.ZodEffects<z.ZodArray<z.ZodEffects<z.ZodString, string, string>, "many">, string[], string[]>;
41
+ customer: z.ZodObject<{
42
+ email: z.ZodPipeline<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, z.ZodString>;
43
+ name: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
44
+ reference: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
45
+ }, "strip", z.ZodTypeAny, {
46
+ email: string;
47
+ name?: string | undefined;
48
+ reference?: string | undefined;
49
+ }, {
50
+ email: string;
51
+ name?: string | undefined;
52
+ reference?: string | undefined;
53
+ }>;
54
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
55
+ callbackUrl: z.ZodOptional<z.ZodString>;
56
+ apiBaseUrl: z.ZodOptional<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>>;
57
+ button: z.ZodOptional<z.ZodObject<{
58
+ text: z.ZodOptional<z.ZodString>;
59
+ className: z.ZodOptional<z.ZodString>;
60
+ theme: z.ZodOptional<z.ZodEnum<["solid", "light", "outline"]>>;
61
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
62
+ }, "strip", z.ZodTypeAny, {
63
+ text?: string | undefined;
64
+ className?: string | undefined;
65
+ theme?: "solid" | "light" | "outline" | undefined;
66
+ style?: Record<string, string> | undefined;
67
+ }, {
68
+ text?: string | undefined;
69
+ className?: string | undefined;
70
+ theme?: "solid" | "light" | "outline" | undefined;
71
+ style?: Record<string, string> | undefined;
72
+ }>>;
73
+ hooks: z.ZodOptional<z.ZodObject<{
74
+ onOpen: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
75
+ onClose: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
76
+ onSessionCreated: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
77
+ onCurrencySelected: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
78
+ onStatusChange: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
79
+ onSuccess: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
80
+ onFail: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>>;
81
+ }, "strip", z.ZodTypeAny, {
82
+ onOpen?: ((...args: unknown[]) => unknown) | undefined;
83
+ onClose?: ((...args: unknown[]) => unknown) | undefined;
84
+ onSessionCreated?: ((...args: unknown[]) => unknown) | undefined;
85
+ onCurrencySelected?: ((...args: unknown[]) => unknown) | undefined;
86
+ onStatusChange?: ((...args: unknown[]) => unknown) | undefined;
87
+ onSuccess?: ((...args: unknown[]) => unknown) | undefined;
88
+ onFail?: ((...args: unknown[]) => unknown) | undefined;
89
+ }, {
90
+ onOpen?: ((...args: unknown[]) => unknown) | undefined;
91
+ onClose?: ((...args: unknown[]) => unknown) | undefined;
92
+ onSessionCreated?: ((...args: unknown[]) => unknown) | undefined;
93
+ onCurrencySelected?: ((...args: unknown[]) => unknown) | undefined;
94
+ onStatusChange?: ((...args: unknown[]) => unknown) | undefined;
95
+ onSuccess?: ((...args: unknown[]) => unknown) | undefined;
96
+ onFail?: ((...args: unknown[]) => unknown) | undefined;
97
+ }>>;
98
+ requestTimeoutMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
99
+ pollIntervalMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
100
+ }, "strip", z.ZodTypeAny, {
101
+ publicKey: string;
102
+ amountNgn: number;
103
+ currencies: string[];
104
+ customer: {
105
+ email: string;
106
+ name?: string | undefined;
107
+ reference?: string | undefined;
108
+ };
109
+ requestTimeoutMs: number;
110
+ pollIntervalMs: number;
111
+ metadata?: Record<string, any> | undefined;
112
+ callbackUrl?: string | undefined;
113
+ apiBaseUrl?: string | undefined;
114
+ button?: {
115
+ text?: string | undefined;
116
+ className?: string | undefined;
117
+ theme?: "solid" | "light" | "outline" | undefined;
118
+ style?: Record<string, string> | undefined;
119
+ } | undefined;
120
+ hooks?: {
121
+ onOpen?: ((...args: unknown[]) => unknown) | undefined;
122
+ onClose?: ((...args: unknown[]) => unknown) | undefined;
123
+ onSessionCreated?: ((...args: unknown[]) => unknown) | undefined;
124
+ onCurrencySelected?: ((...args: unknown[]) => unknown) | undefined;
125
+ onStatusChange?: ((...args: unknown[]) => unknown) | undefined;
126
+ onSuccess?: ((...args: unknown[]) => unknown) | undefined;
127
+ onFail?: ((...args: unknown[]) => unknown) | undefined;
128
+ } | undefined;
129
+ }, {
130
+ publicKey: string;
131
+ amountNgn: number;
132
+ currencies: string[];
133
+ customer: {
134
+ email: string;
135
+ name?: string | undefined;
136
+ reference?: string | undefined;
137
+ };
138
+ metadata?: Record<string, any> | undefined;
139
+ callbackUrl?: string | undefined;
140
+ apiBaseUrl?: string | undefined;
141
+ button?: {
142
+ text?: string | undefined;
143
+ className?: string | undefined;
144
+ theme?: "solid" | "light" | "outline" | undefined;
145
+ style?: Record<string, string> | undefined;
146
+ } | undefined;
147
+ hooks?: {
148
+ onOpen?: ((...args: unknown[]) => unknown) | undefined;
149
+ onClose?: ((...args: unknown[]) => unknown) | undefined;
150
+ onSessionCreated?: ((...args: unknown[]) => unknown) | undefined;
151
+ onCurrencySelected?: ((...args: unknown[]) => unknown) | undefined;
152
+ onStatusChange?: ((...args: unknown[]) => unknown) | undefined;
153
+ onSuccess?: ((...args: unknown[]) => unknown) | undefined;
154
+ onFail?: ((...args: unknown[]) => unknown) | undefined;
155
+ } | undefined;
156
+ requestTimeoutMs?: number | undefined;
157
+ pollIntervalMs?: number | undefined;
158
+ }>;
159
+ export type CheckoutConfig = z.infer<typeof checkoutConfigSchema>;
package/dist/types.js ADDED
@@ -0,0 +1,89 @@
1
+ import { z } from "zod";
2
+ export const NATIVE_CURRENCIES = [
3
+ "BTC",
4
+ "ETH",
5
+ "BNB",
6
+ "MATIC",
7
+ "AVAX",
8
+ "SOL",
9
+ "TRX",
10
+ "LSK",
11
+ "FLOW",
12
+ "RON",
13
+ "SEI",
14
+ "FTM",
15
+ "HBAR",
16
+ ];
17
+ export const T9N_DEFAULT_API_BASE_URL = "https://slimepay.com";
18
+ const trimmedString = () => z
19
+ .string()
20
+ .transform((v) => v.trim())
21
+ .refine((v) => v.length > 0, { message: "Value is required" });
22
+ export const checkoutConfigSchema = z.object({
23
+ publicKey: trimmedString().refine((v) => /^pk_(live|test)_[a-zA-Z0-9_]+$/.test(v), {
24
+ message: "publicKey must follow pk_live_* or pk_test_* format",
25
+ }),
26
+ amountNgn: z.number().finite().positive(),
27
+ currencies: z
28
+ .array(z.string().transform((v) => v.trim().toUpperCase()))
29
+ .min(1, { message: "At least one supported native currency is required" })
30
+ .max(13, { message: "Too many currencies provided" })
31
+ .superRefine((list, ctx) => {
32
+ const supported = new Set(NATIVE_CURRENCIES);
33
+ const seen = new Set();
34
+ for (const [index, currency] of list.entries()) {
35
+ if (!supported.has(currency)) {
36
+ ctx.addIssue({
37
+ code: z.ZodIssueCode.custom,
38
+ message: `Unsupported currency: ${currency}`,
39
+ path: [index],
40
+ });
41
+ }
42
+ if (seen.has(currency)) {
43
+ ctx.addIssue({
44
+ code: z.ZodIssueCode.custom,
45
+ message: "Duplicate currencies are not allowed",
46
+ path: [index],
47
+ });
48
+ }
49
+ seen.add(currency);
50
+ }
51
+ }),
52
+ customer: z.object({
53
+ email: z
54
+ .string()
55
+ .transform((v) => v.trim().toLowerCase())
56
+ .refine((v) => v.length > 0, { message: "customer.email is required" })
57
+ .pipe(z.string().email("customer.email must be a valid email")),
58
+ name: z.string().transform((v) => v.trim()).optional(),
59
+ reference: z.string().transform((v) => v.trim()).optional(),
60
+ }),
61
+ metadata: z.record(z.any()).optional(),
62
+ callbackUrl: z.string().url().optional(),
63
+ apiBaseUrl: z
64
+ .string()
65
+ .transform((v) => v.trim())
66
+ .pipe(z.string().url("apiBaseUrl must be a valid URL"))
67
+ .optional(),
68
+ button: z
69
+ .object({
70
+ text: z.string().min(1).optional(),
71
+ className: z.string().optional(),
72
+ theme: z.enum(["solid", "light", "outline"]).optional(),
73
+ style: z.record(z.string()).optional(),
74
+ })
75
+ .optional(),
76
+ hooks: z
77
+ .object({
78
+ onOpen: z.function().optional(),
79
+ onClose: z.function().optional(),
80
+ onSessionCreated: z.function().optional(),
81
+ onCurrencySelected: z.function().optional(),
82
+ onStatusChange: z.function().optional(),
83
+ onSuccess: z.function().optional(),
84
+ onFail: z.function().optional(),
85
+ })
86
+ .optional(),
87
+ requestTimeoutMs: z.number().min(3000).max(30000).optional().default(12000),
88
+ pollIntervalMs: z.number().min(3000).max(15000).optional().default(5000),
89
+ });
@@ -0,0 +1,45 @@
1
+ export type ModalHandlers = {
2
+ onSelectCurrency: (currency: string) => Promise<void>;
3
+ onConfirmPayment: () => Promise<void>;
4
+ onClose: () => void;
5
+ };
6
+ export declare class CheckoutModal {
7
+ private currencies;
8
+ private handlers;
9
+ private host;
10
+ private root;
11
+ private timerEl;
12
+ private addressEl;
13
+ private qrEl;
14
+ private statusEl;
15
+ private disclaimerEl;
16
+ private confirmBtn;
17
+ private copyBtn;
18
+ private backBtn;
19
+ private actionsContainer;
20
+ private selectionSection;
21
+ private paymentSection;
22
+ private resultSection;
23
+ private resultTitle;
24
+ private resultMessage;
25
+ private resultIcon;
26
+ private retryBtn;
27
+ private resultCloseBtn;
28
+ private chips;
29
+ private confirmLabel;
30
+ private selectedCurrency;
31
+ constructor(currencies: string[], handlers: ModalHandlers);
32
+ private mount;
33
+ private handleCurrencySelect;
34
+ setConfirmLabel(label: string): void;
35
+ setTimer(value: string): void;
36
+ setAddress(address: string): void;
37
+ setQrPayload(payload: string): void;
38
+ setStatus(message: string): void;
39
+ setDisclaimer(message: string): void;
40
+ setConfirmPending(pending: boolean): void;
41
+ showResult(status: "success" | "failed", message: string): void;
42
+ showPaymentView(): void;
43
+ private resetSelection;
44
+ close(): void;
45
+ }