@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 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;
@@ -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 };
@@ -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;
@@ -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 };
@@ -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
+ }