@xorr-finance/irion-sdk 0.1.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.
- package/README.md +105 -0
- package/dist/chunk-6Y4GUDXC.js +51 -0
- package/dist/index.cjs +104 -0
- package/dist/index.d.cts +59 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +51 -0
- package/dist/react.cjs +104 -0
- package/dist/react.d.cts +32 -0
- package/dist/react.d.ts +32 -0
- package/dist/react.js +32 -0
- package/dist/types-Bk6JSyrl.d.cts +60 -0
- package/dist/types-Bk6JSyrl.d.ts +60 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# @xorr-finance/irion-sdk
|
|
2
|
+
|
|
3
|
+
Drop-in **"Buy Now, Pay Never"** checkout for any merchant or shopping site —
|
|
4
|
+
powered by Irion private consumer credit on Canton. Like a payment-gateway SDK
|
|
5
|
+
(Stripe-style): create a checkout on your server with an API key, open it in the
|
|
6
|
+
browser, get the result back.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @xorr-finance/irion-sdk
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
> Migrating from `@xorr/sdk`? The old names (`XorrClient`, `openXorrCheckout`,
|
|
13
|
+
> `PayWithXorr`, `XorrConfig`) are still exported as deprecated aliases, and the
|
|
14
|
+
> `txDigest` field is kept alongside the new `txHash`, so existing code keeps
|
|
15
|
+
> working.
|
|
16
|
+
|
|
17
|
+
## 1. Get your API keys
|
|
18
|
+
|
|
19
|
+
From the **Irion merchant dashboard** → your App → API credentials, copy:
|
|
20
|
+
|
|
21
|
+
- `client_id` → `x-client-id` (public)
|
|
22
|
+
- `client_secret` → `x-client-secret` (**secret — server only**)
|
|
23
|
+
|
|
24
|
+
## 2. Create a checkout (server-side)
|
|
25
|
+
|
|
26
|
+
`clientSecret` must never reach the browser, so create the session in your
|
|
27
|
+
backend (API route / server action / serverless fn):
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { IrionClient } from "@xorr-finance/irion-sdk";
|
|
31
|
+
|
|
32
|
+
const irion = new IrionClient({
|
|
33
|
+
clientId: process.env.IRION_CLIENT_ID!,
|
|
34
|
+
clientSecret: process.env.IRION_CLIENT_SECRET!,
|
|
35
|
+
// baseUrl: "http://localhost:3001", // self-hosted / local dev; omit for hosted gateway
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// e.g. inside POST /api/irion-checkout
|
|
39
|
+
const { checkoutUrl, billHash } = await irion.createCheckout({
|
|
40
|
+
amount: 49.99, // in USDC
|
|
41
|
+
orderId: "cart_8842",
|
|
42
|
+
description: "Sneakers x1",
|
|
43
|
+
});
|
|
44
|
+
return Response.json({ checkoutUrl });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 3. Open the checkout (browser)
|
|
48
|
+
|
|
49
|
+
### Vanilla JS / any framework
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { openIrionCheckout } from "@xorr-finance/irion-sdk";
|
|
53
|
+
|
|
54
|
+
const { checkoutUrl } = await fetch("/api/irion-checkout", { method: "POST" }).then(r => r.json());
|
|
55
|
+
|
|
56
|
+
openIrionCheckout(checkoutUrl, {
|
|
57
|
+
onSuccess: (r) => console.log("paid!", r.txHash, r.loanId),
|
|
58
|
+
onError: (r) => console.warn("failed", r.error),
|
|
59
|
+
onClose: () => console.log("shopper closed checkout"),
|
|
60
|
+
// redirect: true, // full-page redirect instead of a popup
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### React
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { PayWithIrion } from "@xorr-finance/irion-sdk/react";
|
|
68
|
+
|
|
69
|
+
<PayWithIrion
|
|
70
|
+
createCheckout={() => fetch("/api/irion-checkout", { method: "POST" }).then(r => r.json())}
|
|
71
|
+
onSuccess={(r) => router.push(`/success?tx=${r.txHash}`)}
|
|
72
|
+
/>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## How payment works
|
|
76
|
+
|
|
77
|
+
The shopper picks **Pay Never** (over-collateralized BNPL: their collateral
|
|
78
|
+
earns yield that auto-repays the purchase) or pays in full. Their credit is
|
|
79
|
+
scored **privately** — income/debts stay in a private Daml contract that only the
|
|
80
|
+
shopper and the operator can see, never the wider network. Settlement happens on
|
|
81
|
+
Canton; you get the `txHash` + `loanId` back.
|
|
82
|
+
|
|
83
|
+
## Result shape (`postMessage` / callbacks)
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
interface PaymentResult {
|
|
87
|
+
success: boolean;
|
|
88
|
+
billHash?: string;
|
|
89
|
+
loanId?: string; // on-chain BNPL loan id
|
|
90
|
+
txHash?: string; // Canton settlement id (update id)
|
|
91
|
+
txDigest?: string; // @deprecated legacy alias for txHash (Sui era)
|
|
92
|
+
paymentMode?: "bnpl" | "split3" | "full";
|
|
93
|
+
error?: string;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## API
|
|
98
|
+
|
|
99
|
+
| Export | Where | Purpose |
|
|
100
|
+
|--------|-------|---------|
|
|
101
|
+
| `new IrionClient(config)` | server | `createCheckout(params)`, `getBill(hash)`, `checkoutUrl(hash)` |
|
|
102
|
+
| `openIrionCheckout(url, opts)` | browser | opens the checkout popup, resolves via callbacks |
|
|
103
|
+
| `<PayWithIrion/>` (`@xorr-finance/irion-sdk/react`) | browser | prebuilt button |
|
|
104
|
+
|
|
105
|
+
MIT.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/browser.ts
|
|
2
|
+
var RESULT_TYPES = ["IRION_PAYMENT_RESULT", "XORR_PAYMENT_RESULT", "POLARIS_PAYMENT_RESULT"];
|
|
3
|
+
function openIrionCheckout(checkoutUrl, options = {}) {
|
|
4
|
+
if (typeof window === "undefined") {
|
|
5
|
+
throw new Error("openIrionCheckout must run in the browser. Create the checkout server-side with IrionClient, then call this on the client.");
|
|
6
|
+
}
|
|
7
|
+
if (options.redirect) {
|
|
8
|
+
window.location.href = checkoutUrl;
|
|
9
|
+
return () => {
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
const expectedOrigin = options.allowedOrigin ?? (() => {
|
|
13
|
+
try {
|
|
14
|
+
return new URL(checkoutUrl).origin;
|
|
15
|
+
} catch {
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
18
|
+
})();
|
|
19
|
+
const w = options.width ?? 460;
|
|
20
|
+
const h = options.height ?? 720;
|
|
21
|
+
const left = window.screenX + Math.max(0, (window.outerWidth - w) / 2);
|
|
22
|
+
const top = window.screenY + Math.max(0, (window.outerHeight - h) / 2);
|
|
23
|
+
const popup = window.open(checkoutUrl, "irion-checkout", `popup,width=${w},height=${h},left=${left},top=${top}`);
|
|
24
|
+
const handler = (event) => {
|
|
25
|
+
if (expectedOrigin && event.origin !== expectedOrigin) return;
|
|
26
|
+
const data = event.data;
|
|
27
|
+
if (!data || !data.type || !RESULT_TYPES.includes(data.type)) return;
|
|
28
|
+
if (data.success) options.onSuccess?.(data);
|
|
29
|
+
else options.onError?.(data);
|
|
30
|
+
cleanup();
|
|
31
|
+
};
|
|
32
|
+
const poll = window.setInterval(() => {
|
|
33
|
+
if (popup && popup.closed) {
|
|
34
|
+
cleanup();
|
|
35
|
+
options.onClose?.();
|
|
36
|
+
}
|
|
37
|
+
}, 600);
|
|
38
|
+
function cleanup() {
|
|
39
|
+
window.removeEventListener("message", handler);
|
|
40
|
+
window.clearInterval(poll);
|
|
41
|
+
try {
|
|
42
|
+
popup?.close();
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
window.addEventListener("message", handler);
|
|
47
|
+
return cleanup;
|
|
48
|
+
}
|
|
49
|
+
var openXorrCheckout = openIrionCheckout;
|
|
50
|
+
|
|
51
|
+
export { openIrionCheckout, openXorrCheckout };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
var DEFAULT_BASE_URL = "https://pay.irion.finance";
|
|
5
|
+
var IrionClient = class {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
if (!config?.clientId || !config?.clientSecret) {
|
|
8
|
+
throw new Error("IrionClient: `clientId` and `clientSecret` are required (get them from the Irion merchant dashboard).");
|
|
9
|
+
}
|
|
10
|
+
this.clientId = config.clientId;
|
|
11
|
+
this.clientSecret = config.clientSecret;
|
|
12
|
+
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
13
|
+
this.asset = config.asset ?? "USDC";
|
|
14
|
+
}
|
|
15
|
+
/** Create a BNPL checkout session. Returns a `checkoutUrl` to open/redirect the shopper to. */
|
|
16
|
+
async createCheckout(params) {
|
|
17
|
+
if (!params?.amount || params.amount <= 0) throw new Error("IrionClient.createCheckout: `amount` must be > 0");
|
|
18
|
+
const res = await fetch(`${this.baseUrl}/api/bills/create`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
"x-client-id": this.clientId,
|
|
23
|
+
"x-client-secret": this.clientSecret
|
|
24
|
+
},
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
amount: params.amount,
|
|
27
|
+
description: params.description,
|
|
28
|
+
asset: params.asset ?? this.asset,
|
|
29
|
+
metadata: { ...params.metadata ?? {}, ...params.orderId ? { orderId: params.orderId } : {} }
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
const detail = await res.text().catch(() => "");
|
|
34
|
+
throw new Error(`Irion createCheckout failed (${res.status}): ${detail || res.statusText}`);
|
|
35
|
+
}
|
|
36
|
+
return await res.json();
|
|
37
|
+
}
|
|
38
|
+
/** Fetch the current state of a bill (e.g. to confirm payment server-side). */
|
|
39
|
+
async getBill(billHash) {
|
|
40
|
+
const res = await fetch(`${this.baseUrl}/api/bills/${billHash}`);
|
|
41
|
+
if (!res.ok) throw new Error(`Irion getBill failed (${res.status})`);
|
|
42
|
+
return await res.json();
|
|
43
|
+
}
|
|
44
|
+
/** The checkout URL for a bill hash (if you already have one). */
|
|
45
|
+
checkoutUrl(billHash) {
|
|
46
|
+
return `${this.baseUrl}/pay/${billHash}`;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var XorrClient = IrionClient;
|
|
50
|
+
|
|
51
|
+
// src/browser.ts
|
|
52
|
+
var RESULT_TYPES = ["IRION_PAYMENT_RESULT", "XORR_PAYMENT_RESULT", "POLARIS_PAYMENT_RESULT"];
|
|
53
|
+
function openIrionCheckout(checkoutUrl, options = {}) {
|
|
54
|
+
if (typeof window === "undefined") {
|
|
55
|
+
throw new Error("openIrionCheckout must run in the browser. Create the checkout server-side with IrionClient, then call this on the client.");
|
|
56
|
+
}
|
|
57
|
+
if (options.redirect) {
|
|
58
|
+
window.location.href = checkoutUrl;
|
|
59
|
+
return () => {
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const expectedOrigin = options.allowedOrigin ?? (() => {
|
|
63
|
+
try {
|
|
64
|
+
return new URL(checkoutUrl).origin;
|
|
65
|
+
} catch {
|
|
66
|
+
return void 0;
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
const w = options.width ?? 460;
|
|
70
|
+
const h = options.height ?? 720;
|
|
71
|
+
const left = window.screenX + Math.max(0, (window.outerWidth - w) / 2);
|
|
72
|
+
const top = window.screenY + Math.max(0, (window.outerHeight - h) / 2);
|
|
73
|
+
const popup = window.open(checkoutUrl, "irion-checkout", `popup,width=${w},height=${h},left=${left},top=${top}`);
|
|
74
|
+
const handler = (event) => {
|
|
75
|
+
if (expectedOrigin && event.origin !== expectedOrigin) return;
|
|
76
|
+
const data = event.data;
|
|
77
|
+
if (!data || !data.type || !RESULT_TYPES.includes(data.type)) return;
|
|
78
|
+
if (data.success) options.onSuccess?.(data);
|
|
79
|
+
else options.onError?.(data);
|
|
80
|
+
cleanup();
|
|
81
|
+
};
|
|
82
|
+
const poll = window.setInterval(() => {
|
|
83
|
+
if (popup && popup.closed) {
|
|
84
|
+
cleanup();
|
|
85
|
+
options.onClose?.();
|
|
86
|
+
}
|
|
87
|
+
}, 600);
|
|
88
|
+
function cleanup() {
|
|
89
|
+
window.removeEventListener("message", handler);
|
|
90
|
+
window.clearInterval(poll);
|
|
91
|
+
try {
|
|
92
|
+
popup?.close();
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
window.addEventListener("message", handler);
|
|
97
|
+
return cleanup;
|
|
98
|
+
}
|
|
99
|
+
var openXorrCheckout = openIrionCheckout;
|
|
100
|
+
|
|
101
|
+
exports.IrionClient = IrionClient;
|
|
102
|
+
exports.XorrClient = XorrClient;
|
|
103
|
+
exports.openIrionCheckout = openIrionCheckout;
|
|
104
|
+
exports.openXorrCheckout = openXorrCheckout;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { I as IrionConfig, C as CreateCheckoutParams, a as Checkout, B as Bill, P as PaymentResult } from './types-Bk6JSyrl.cjs';
|
|
2
|
+
export { X as XorrConfig } from './types-Bk6JSyrl.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Server-side Irion client. Use it in your backend (API route, server action,
|
|
6
|
+
* serverless function) to create checkout sessions — NEVER expose
|
|
7
|
+
* `clientSecret` to the browser.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const irion = new IrionClient({ clientId: process.env.IRION_CLIENT_ID!, clientSecret: process.env.IRION_CLIENT_SECRET! });
|
|
11
|
+
* const { checkoutUrl } = await irion.createCheckout({ amount: 49.99, orderId: "cart_123" });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
declare class IrionClient {
|
|
15
|
+
private readonly clientId;
|
|
16
|
+
private readonly clientSecret;
|
|
17
|
+
private readonly baseUrl;
|
|
18
|
+
private readonly asset;
|
|
19
|
+
constructor(config: IrionConfig);
|
|
20
|
+
/** Create a BNPL checkout session. Returns a `checkoutUrl` to open/redirect the shopper to. */
|
|
21
|
+
createCheckout(params: CreateCheckoutParams): Promise<Checkout>;
|
|
22
|
+
/** Fetch the current state of a bill (e.g. to confirm payment server-side). */
|
|
23
|
+
getBill(billHash: string): Promise<Bill>;
|
|
24
|
+
/** The checkout URL for a bill hash (if you already have one). */
|
|
25
|
+
checkoutUrl(billHash: string): string;
|
|
26
|
+
}
|
|
27
|
+
/** @deprecated Renamed to {@link IrionClient}. Kept for back-compat. */
|
|
28
|
+
declare const XorrClient: typeof IrionClient;
|
|
29
|
+
|
|
30
|
+
interface OpenCheckoutOptions {
|
|
31
|
+
/** Called when the shopper completes payment. */
|
|
32
|
+
onSuccess?: (result: PaymentResult) => void;
|
|
33
|
+
/** Called on a failed/cancelled payment. */
|
|
34
|
+
onError?: (result: PaymentResult) => void;
|
|
35
|
+
/** Called if the shopper closes the popup without finishing. */
|
|
36
|
+
onClose?: () => void;
|
|
37
|
+
/** Open in the same tab via redirect instead of a popup. */
|
|
38
|
+
redirect?: boolean;
|
|
39
|
+
/** Only accept payment-result messages from this exact origin. Defaults to the checkout URL's origin. */
|
|
40
|
+
allowedOrigin?: string;
|
|
41
|
+
width?: number;
|
|
42
|
+
height?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Open the Irion checkout (browser-only) and resolve via callbacks when the
|
|
46
|
+
* shopper finishes. Returns a `cancel()` you can call to tear down listeners.
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* openIrionCheckout(checkoutUrl, {
|
|
50
|
+
* onSuccess: (r) => console.log("paid!", r.txHash),
|
|
51
|
+
* onError: (r) => console.warn(r.error),
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function openIrionCheckout(checkoutUrl: string, options?: OpenCheckoutOptions): () => void;
|
|
56
|
+
/** @deprecated Renamed to {@link openIrionCheckout}. Kept for back-compat. */
|
|
57
|
+
declare const openXorrCheckout: typeof openIrionCheckout;
|
|
58
|
+
|
|
59
|
+
export { Bill, Checkout, CreateCheckoutParams, IrionClient, IrionConfig, type OpenCheckoutOptions, PaymentResult, XorrClient, openIrionCheckout, openXorrCheckout };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { I as IrionConfig, C as CreateCheckoutParams, a as Checkout, B as Bill, P as PaymentResult } from './types-Bk6JSyrl.js';
|
|
2
|
+
export { X as XorrConfig } from './types-Bk6JSyrl.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Server-side Irion client. Use it in your backend (API route, server action,
|
|
6
|
+
* serverless function) to create checkout sessions — NEVER expose
|
|
7
|
+
* `clientSecret` to the browser.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const irion = new IrionClient({ clientId: process.env.IRION_CLIENT_ID!, clientSecret: process.env.IRION_CLIENT_SECRET! });
|
|
11
|
+
* const { checkoutUrl } = await irion.createCheckout({ amount: 49.99, orderId: "cart_123" });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
declare class IrionClient {
|
|
15
|
+
private readonly clientId;
|
|
16
|
+
private readonly clientSecret;
|
|
17
|
+
private readonly baseUrl;
|
|
18
|
+
private readonly asset;
|
|
19
|
+
constructor(config: IrionConfig);
|
|
20
|
+
/** Create a BNPL checkout session. Returns a `checkoutUrl` to open/redirect the shopper to. */
|
|
21
|
+
createCheckout(params: CreateCheckoutParams): Promise<Checkout>;
|
|
22
|
+
/** Fetch the current state of a bill (e.g. to confirm payment server-side). */
|
|
23
|
+
getBill(billHash: string): Promise<Bill>;
|
|
24
|
+
/** The checkout URL for a bill hash (if you already have one). */
|
|
25
|
+
checkoutUrl(billHash: string): string;
|
|
26
|
+
}
|
|
27
|
+
/** @deprecated Renamed to {@link IrionClient}. Kept for back-compat. */
|
|
28
|
+
declare const XorrClient: typeof IrionClient;
|
|
29
|
+
|
|
30
|
+
interface OpenCheckoutOptions {
|
|
31
|
+
/** Called when the shopper completes payment. */
|
|
32
|
+
onSuccess?: (result: PaymentResult) => void;
|
|
33
|
+
/** Called on a failed/cancelled payment. */
|
|
34
|
+
onError?: (result: PaymentResult) => void;
|
|
35
|
+
/** Called if the shopper closes the popup without finishing. */
|
|
36
|
+
onClose?: () => void;
|
|
37
|
+
/** Open in the same tab via redirect instead of a popup. */
|
|
38
|
+
redirect?: boolean;
|
|
39
|
+
/** Only accept payment-result messages from this exact origin. Defaults to the checkout URL's origin. */
|
|
40
|
+
allowedOrigin?: string;
|
|
41
|
+
width?: number;
|
|
42
|
+
height?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Open the Irion checkout (browser-only) and resolve via callbacks when the
|
|
46
|
+
* shopper finishes. Returns a `cancel()` you can call to tear down listeners.
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* openIrionCheckout(checkoutUrl, {
|
|
50
|
+
* onSuccess: (r) => console.log("paid!", r.txHash),
|
|
51
|
+
* onError: (r) => console.warn(r.error),
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function openIrionCheckout(checkoutUrl: string, options?: OpenCheckoutOptions): () => void;
|
|
56
|
+
/** @deprecated Renamed to {@link openIrionCheckout}. Kept for back-compat. */
|
|
57
|
+
declare const openXorrCheckout: typeof openIrionCheckout;
|
|
58
|
+
|
|
59
|
+
export { Bill, Checkout, CreateCheckoutParams, IrionClient, IrionConfig, type OpenCheckoutOptions, PaymentResult, XorrClient, openIrionCheckout, openXorrCheckout };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export { openIrionCheckout, openXorrCheckout } from './chunk-6Y4GUDXC.js';
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
var DEFAULT_BASE_URL = "https://pay.irion.finance";
|
|
5
|
+
var IrionClient = class {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
if (!config?.clientId || !config?.clientSecret) {
|
|
8
|
+
throw new Error("IrionClient: `clientId` and `clientSecret` are required (get them from the Irion merchant dashboard).");
|
|
9
|
+
}
|
|
10
|
+
this.clientId = config.clientId;
|
|
11
|
+
this.clientSecret = config.clientSecret;
|
|
12
|
+
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
13
|
+
this.asset = config.asset ?? "USDC";
|
|
14
|
+
}
|
|
15
|
+
/** Create a BNPL checkout session. Returns a `checkoutUrl` to open/redirect the shopper to. */
|
|
16
|
+
async createCheckout(params) {
|
|
17
|
+
if (!params?.amount || params.amount <= 0) throw new Error("IrionClient.createCheckout: `amount` must be > 0");
|
|
18
|
+
const res = await fetch(`${this.baseUrl}/api/bills/create`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
"x-client-id": this.clientId,
|
|
23
|
+
"x-client-secret": this.clientSecret
|
|
24
|
+
},
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
amount: params.amount,
|
|
27
|
+
description: params.description,
|
|
28
|
+
asset: params.asset ?? this.asset,
|
|
29
|
+
metadata: { ...params.metadata ?? {}, ...params.orderId ? { orderId: params.orderId } : {} }
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
const detail = await res.text().catch(() => "");
|
|
34
|
+
throw new Error(`Irion createCheckout failed (${res.status}): ${detail || res.statusText}`);
|
|
35
|
+
}
|
|
36
|
+
return await res.json();
|
|
37
|
+
}
|
|
38
|
+
/** Fetch the current state of a bill (e.g. to confirm payment server-side). */
|
|
39
|
+
async getBill(billHash) {
|
|
40
|
+
const res = await fetch(`${this.baseUrl}/api/bills/${billHash}`);
|
|
41
|
+
if (!res.ok) throw new Error(`Irion getBill failed (${res.status})`);
|
|
42
|
+
return await res.json();
|
|
43
|
+
}
|
|
44
|
+
/** The checkout URL for a bill hash (if you already have one). */
|
|
45
|
+
checkoutUrl(billHash) {
|
|
46
|
+
return `${this.baseUrl}/pay/${billHash}`;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var XorrClient = IrionClient;
|
|
50
|
+
|
|
51
|
+
export { IrionClient, XorrClient };
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
25
|
+
|
|
26
|
+
// src/react.tsx
|
|
27
|
+
|
|
28
|
+
// src/browser.ts
|
|
29
|
+
var RESULT_TYPES = ["IRION_PAYMENT_RESULT", "XORR_PAYMENT_RESULT", "POLARIS_PAYMENT_RESULT"];
|
|
30
|
+
function openIrionCheckout(checkoutUrl, options = {}) {
|
|
31
|
+
if (typeof window === "undefined") {
|
|
32
|
+
throw new Error("openIrionCheckout must run in the browser. Create the checkout server-side with IrionClient, then call this on the client.");
|
|
33
|
+
}
|
|
34
|
+
if (options.redirect) {
|
|
35
|
+
window.location.href = checkoutUrl;
|
|
36
|
+
return () => {
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const expectedOrigin = options.allowedOrigin ?? (() => {
|
|
40
|
+
try {
|
|
41
|
+
return new URL(checkoutUrl).origin;
|
|
42
|
+
} catch {
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
})();
|
|
46
|
+
const w = options.width ?? 460;
|
|
47
|
+
const h = options.height ?? 720;
|
|
48
|
+
const left = window.screenX + Math.max(0, (window.outerWidth - w) / 2);
|
|
49
|
+
const top = window.screenY + Math.max(0, (window.outerHeight - h) / 2);
|
|
50
|
+
const popup = window.open(checkoutUrl, "irion-checkout", `popup,width=${w},height=${h},left=${left},top=${top}`);
|
|
51
|
+
const handler = (event) => {
|
|
52
|
+
if (expectedOrigin && event.origin !== expectedOrigin) return;
|
|
53
|
+
const data = event.data;
|
|
54
|
+
if (!data || !data.type || !RESULT_TYPES.includes(data.type)) return;
|
|
55
|
+
if (data.success) options.onSuccess?.(data);
|
|
56
|
+
else options.onError?.(data);
|
|
57
|
+
cleanup();
|
|
58
|
+
};
|
|
59
|
+
const poll = window.setInterval(() => {
|
|
60
|
+
if (popup && popup.closed) {
|
|
61
|
+
cleanup();
|
|
62
|
+
options.onClose?.();
|
|
63
|
+
}
|
|
64
|
+
}, 600);
|
|
65
|
+
function cleanup() {
|
|
66
|
+
window.removeEventListener("message", handler);
|
|
67
|
+
window.clearInterval(poll);
|
|
68
|
+
try {
|
|
69
|
+
popup?.close();
|
|
70
|
+
} catch {
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
window.addEventListener("message", handler);
|
|
74
|
+
return cleanup;
|
|
75
|
+
}
|
|
76
|
+
function PayWithIrion({ checkoutUrl, createCheckout, onSuccess, onError, className, style, children }) {
|
|
77
|
+
const [loading, setLoading] = React__namespace.useState(false);
|
|
78
|
+
const handleClick = async () => {
|
|
79
|
+
setLoading(true);
|
|
80
|
+
try {
|
|
81
|
+
const url = checkoutUrl ?? (await createCheckout?.())?.checkoutUrl;
|
|
82
|
+
if (!url) throw new Error("PayWithIrion: provide `checkoutUrl` or a `createCheckout` that returns one.");
|
|
83
|
+
openIrionCheckout(url, {
|
|
84
|
+
onSuccess: (r) => {
|
|
85
|
+
setLoading(false);
|
|
86
|
+
onSuccess?.(r);
|
|
87
|
+
},
|
|
88
|
+
onError: (r) => {
|
|
89
|
+
setLoading(false);
|
|
90
|
+
onError?.(r);
|
|
91
|
+
},
|
|
92
|
+
onClose: () => setLoading(false)
|
|
93
|
+
});
|
|
94
|
+
} catch (e) {
|
|
95
|
+
setLoading(false);
|
|
96
|
+
onError?.({ success: false, error: e instanceof Error ? e.message : String(e) });
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: handleClick, disabled: loading, className, style, children: children ?? (loading ? "Opening Irion\u2026" : "Buy Now, Pay Never \u2014 with Irion") });
|
|
100
|
+
}
|
|
101
|
+
var PayWithXorr = PayWithIrion;
|
|
102
|
+
|
|
103
|
+
exports.PayWithIrion = PayWithIrion;
|
|
104
|
+
exports.PayWithXorr = PayWithXorr;
|
package/dist/react.d.cts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { P as PaymentResult } from './types-Bk6JSyrl.cjs';
|
|
3
|
+
|
|
4
|
+
interface PayWithIrionProps {
|
|
5
|
+
/** A checkout URL already created server-side via `IrionClient.createCheckout`. */
|
|
6
|
+
checkoutUrl?: string;
|
|
7
|
+
/** Or a callback (usually hitting your own backend) that returns a fresh one. */
|
|
8
|
+
createCheckout?: () => Promise<{
|
|
9
|
+
checkoutUrl: string;
|
|
10
|
+
}>;
|
|
11
|
+
onSuccess?: (result: PaymentResult) => void;
|
|
12
|
+
onError?: (result: PaymentResult) => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
style?: React.CSSProperties;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/** @deprecated Renamed to {@link PayWithIrionProps}. Kept for back-compat. */
|
|
18
|
+
type PayWithXorrProps = PayWithIrionProps;
|
|
19
|
+
/**
|
|
20
|
+
* Drop-in "Buy Now, Pay Never with Irion" button. Pass a pre-created
|
|
21
|
+
* `checkoutUrl` (recommended) or a `createCheckout` callback.
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <PayWithIrion createCheckout={() => fetch("/api/irion-checkout", {method:"POST"}).then(r=>r.json())}
|
|
25
|
+
* onSuccess={(r) => router.push(`/success?tx=${r.txHash}`)} />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function PayWithIrion({ checkoutUrl, createCheckout, onSuccess, onError, className, style, children }: PayWithIrionProps): React.JSX.Element;
|
|
29
|
+
/** @deprecated Renamed to {@link PayWithIrion}. Kept for back-compat. */
|
|
30
|
+
declare const PayWithXorr: typeof PayWithIrion;
|
|
31
|
+
|
|
32
|
+
export { PayWithIrion, type PayWithIrionProps, PayWithXorr, type PayWithXorrProps };
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { P as PaymentResult } from './types-Bk6JSyrl.js';
|
|
3
|
+
|
|
4
|
+
interface PayWithIrionProps {
|
|
5
|
+
/** A checkout URL already created server-side via `IrionClient.createCheckout`. */
|
|
6
|
+
checkoutUrl?: string;
|
|
7
|
+
/** Or a callback (usually hitting your own backend) that returns a fresh one. */
|
|
8
|
+
createCheckout?: () => Promise<{
|
|
9
|
+
checkoutUrl: string;
|
|
10
|
+
}>;
|
|
11
|
+
onSuccess?: (result: PaymentResult) => void;
|
|
12
|
+
onError?: (result: PaymentResult) => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
style?: React.CSSProperties;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/** @deprecated Renamed to {@link PayWithIrionProps}. Kept for back-compat. */
|
|
18
|
+
type PayWithXorrProps = PayWithIrionProps;
|
|
19
|
+
/**
|
|
20
|
+
* Drop-in "Buy Now, Pay Never with Irion" button. Pass a pre-created
|
|
21
|
+
* `checkoutUrl` (recommended) or a `createCheckout` callback.
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <PayWithIrion createCheckout={() => fetch("/api/irion-checkout", {method:"POST"}).then(r=>r.json())}
|
|
25
|
+
* onSuccess={(r) => router.push(`/success?tx=${r.txHash}`)} />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function PayWithIrion({ checkoutUrl, createCheckout, onSuccess, onError, className, style, children }: PayWithIrionProps): React.JSX.Element;
|
|
29
|
+
/** @deprecated Renamed to {@link PayWithIrion}. Kept for back-compat. */
|
|
30
|
+
declare const PayWithXorr: typeof PayWithIrion;
|
|
31
|
+
|
|
32
|
+
export { PayWithIrion, type PayWithIrionProps, PayWithXorr, type PayWithXorrProps };
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { openIrionCheckout } from './chunk-6Y4GUDXC.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function PayWithIrion({ checkoutUrl, createCheckout, onSuccess, onError, className, style, children }) {
|
|
6
|
+
const [loading, setLoading] = React.useState(false);
|
|
7
|
+
const handleClick = async () => {
|
|
8
|
+
setLoading(true);
|
|
9
|
+
try {
|
|
10
|
+
const url = checkoutUrl ?? (await createCheckout?.())?.checkoutUrl;
|
|
11
|
+
if (!url) throw new Error("PayWithIrion: provide `checkoutUrl` or a `createCheckout` that returns one.");
|
|
12
|
+
openIrionCheckout(url, {
|
|
13
|
+
onSuccess: (r) => {
|
|
14
|
+
setLoading(false);
|
|
15
|
+
onSuccess?.(r);
|
|
16
|
+
},
|
|
17
|
+
onError: (r) => {
|
|
18
|
+
setLoading(false);
|
|
19
|
+
onError?.(r);
|
|
20
|
+
},
|
|
21
|
+
onClose: () => setLoading(false)
|
|
22
|
+
});
|
|
23
|
+
} catch (e) {
|
|
24
|
+
setLoading(false);
|
|
25
|
+
onError?.({ success: false, error: e instanceof Error ? e.message : String(e) });
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClick, disabled: loading, className, style, children: children ?? (loading ? "Opening Irion\u2026" : "Buy Now, Pay Never \u2014 with Irion") });
|
|
29
|
+
}
|
|
30
|
+
var PayWithXorr = PayWithIrion;
|
|
31
|
+
|
|
32
|
+
export { PayWithIrion, PayWithXorr };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Configuration for the server-side {@link IrionClient}. Get your keys from
|
|
2
|
+
* the Irion merchant dashboard (Apps → API credentials). */
|
|
3
|
+
interface IrionConfig {
|
|
4
|
+
/** `x-client-id` — your public merchant app id (e.g. `prod_...`). */
|
|
5
|
+
clientId: string;
|
|
6
|
+
/** `x-client-secret` — KEEP SERVER-SIDE ONLY. Never ship to the browser. */
|
|
7
|
+
clientSecret: string;
|
|
8
|
+
/** Irion API base URL. Defaults to the hosted gateway; point at your
|
|
9
|
+
* self-hosted Irion core/merchant deployment in dev (e.g. http://localhost:3001). */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
/** Settlement asset. Defaults to `USDC`. */
|
|
12
|
+
asset?: string;
|
|
13
|
+
}
|
|
14
|
+
/** @deprecated Renamed to {@link IrionConfig}. Kept for back-compat. */
|
|
15
|
+
type XorrConfig = IrionConfig;
|
|
16
|
+
interface CreateCheckoutParams {
|
|
17
|
+
/** Amount due, in whole `asset` units (e.g. 49.99 USDC). */
|
|
18
|
+
amount: number;
|
|
19
|
+
/** Your order/cart id — echoed back in the payment result. */
|
|
20
|
+
orderId?: string;
|
|
21
|
+
/** Human-readable description shown on the checkout. */
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Arbitrary metadata stored on the bill. */
|
|
24
|
+
metadata?: Record<string, unknown>;
|
|
25
|
+
/** Override the default asset for this checkout. */
|
|
26
|
+
asset?: string;
|
|
27
|
+
}
|
|
28
|
+
interface Checkout {
|
|
29
|
+
billId?: string;
|
|
30
|
+
/** Unique bill hash; the checkout lives at `{baseUrl}/pay/{billHash}`. */
|
|
31
|
+
billHash: string;
|
|
32
|
+
/** URL to open/redirect the shopper to in order to pay. */
|
|
33
|
+
checkoutUrl: string;
|
|
34
|
+
merchantName?: string;
|
|
35
|
+
status: string;
|
|
36
|
+
}
|
|
37
|
+
interface Bill {
|
|
38
|
+
billHash: string;
|
|
39
|
+
amount: number;
|
|
40
|
+
asset: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
status: "pending" | "paid" | "expired" | string;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
/** Posted back to `window.opener` (and resolved by {@link openIrionCheckout}) when
|
|
46
|
+
* the shopper finishes the Irion checkout. */
|
|
47
|
+
interface PaymentResult {
|
|
48
|
+
success: boolean;
|
|
49
|
+
billHash?: string;
|
|
50
|
+
/** On-chain BNPL loan id (if the shopper chose Pay-Never / BNPL). */
|
|
51
|
+
loanId?: string;
|
|
52
|
+
/** Canton settlement id (update id) of the on-ledger transaction. */
|
|
53
|
+
txHash?: string;
|
|
54
|
+
/** @deprecated Use {@link PaymentResult.txHash}. Legacy alias from the Sui era. */
|
|
55
|
+
txDigest?: string;
|
|
56
|
+
paymentMode?: "bnpl" | "split3" | "full";
|
|
57
|
+
error?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type { Bill as B, CreateCheckoutParams as C, IrionConfig as I, PaymentResult as P, XorrConfig as X, Checkout as a };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Configuration for the server-side {@link IrionClient}. Get your keys from
|
|
2
|
+
* the Irion merchant dashboard (Apps → API credentials). */
|
|
3
|
+
interface IrionConfig {
|
|
4
|
+
/** `x-client-id` — your public merchant app id (e.g. `prod_...`). */
|
|
5
|
+
clientId: string;
|
|
6
|
+
/** `x-client-secret` — KEEP SERVER-SIDE ONLY. Never ship to the browser. */
|
|
7
|
+
clientSecret: string;
|
|
8
|
+
/** Irion API base URL. Defaults to the hosted gateway; point at your
|
|
9
|
+
* self-hosted Irion core/merchant deployment in dev (e.g. http://localhost:3001). */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
/** Settlement asset. Defaults to `USDC`. */
|
|
12
|
+
asset?: string;
|
|
13
|
+
}
|
|
14
|
+
/** @deprecated Renamed to {@link IrionConfig}. Kept for back-compat. */
|
|
15
|
+
type XorrConfig = IrionConfig;
|
|
16
|
+
interface CreateCheckoutParams {
|
|
17
|
+
/** Amount due, in whole `asset` units (e.g. 49.99 USDC). */
|
|
18
|
+
amount: number;
|
|
19
|
+
/** Your order/cart id — echoed back in the payment result. */
|
|
20
|
+
orderId?: string;
|
|
21
|
+
/** Human-readable description shown on the checkout. */
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Arbitrary metadata stored on the bill. */
|
|
24
|
+
metadata?: Record<string, unknown>;
|
|
25
|
+
/** Override the default asset for this checkout. */
|
|
26
|
+
asset?: string;
|
|
27
|
+
}
|
|
28
|
+
interface Checkout {
|
|
29
|
+
billId?: string;
|
|
30
|
+
/** Unique bill hash; the checkout lives at `{baseUrl}/pay/{billHash}`. */
|
|
31
|
+
billHash: string;
|
|
32
|
+
/** URL to open/redirect the shopper to in order to pay. */
|
|
33
|
+
checkoutUrl: string;
|
|
34
|
+
merchantName?: string;
|
|
35
|
+
status: string;
|
|
36
|
+
}
|
|
37
|
+
interface Bill {
|
|
38
|
+
billHash: string;
|
|
39
|
+
amount: number;
|
|
40
|
+
asset: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
status: "pending" | "paid" | "expired" | string;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
/** Posted back to `window.opener` (and resolved by {@link openIrionCheckout}) when
|
|
46
|
+
* the shopper finishes the Irion checkout. */
|
|
47
|
+
interface PaymentResult {
|
|
48
|
+
success: boolean;
|
|
49
|
+
billHash?: string;
|
|
50
|
+
/** On-chain BNPL loan id (if the shopper chose Pay-Never / BNPL). */
|
|
51
|
+
loanId?: string;
|
|
52
|
+
/** Canton settlement id (update id) of the on-ledger transaction. */
|
|
53
|
+
txHash?: string;
|
|
54
|
+
/** @deprecated Use {@link PaymentResult.txHash}. Legacy alias from the Sui era. */
|
|
55
|
+
txDigest?: string;
|
|
56
|
+
paymentMode?: "bnpl" | "split3" | "full";
|
|
57
|
+
error?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type { Bill as B, CreateCheckoutParams as C, IrionConfig as I, PaymentResult as P, XorrConfig as X, Checkout as a };
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xorr-finance/irion-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Irion Buy-Now-Pay-Never SDK — private consumer-credit checkout on Canton. Drop-in for any merchant / shopping site.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": { "type": "git", "url": "git+https://github.com/nickthelegend/irion-sdk-canton.git" },
|
|
7
|
+
"homepage": "https://github.com/nickthelegend/irion-sdk-canton#readme",
|
|
8
|
+
"publishConfig": { "access": "public" },
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.cjs",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./react": {
|
|
20
|
+
"types": "./dist/react.d.ts",
|
|
21
|
+
"import": "./dist/react.js",
|
|
22
|
+
"require": "./dist/react.cjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": ["dist", "README.md"],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"dev": "tsup --watch"
|
|
29
|
+
},
|
|
30
|
+
"keywords": ["irion", "bnpl", "canton", "daml", "payments", "checkout", "buy-now-pay-never"],
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": ">=18"
|
|
33
|
+
},
|
|
34
|
+
"peerDependenciesMeta": {
|
|
35
|
+
"react": { "optional": true }
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/react": "^18.3.0",
|
|
39
|
+
"react": "^18.3.0",
|
|
40
|
+
"tsup": "^8.3.0",
|
|
41
|
+
"typescript": "^5.6.0"
|
|
42
|
+
}
|
|
43
|
+
}
|