@settlr/sdk 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  INCO_LIGHTNING_PROGRAM_ID: () => INCO_LIGHTNING_PROGRAM_ID,
36
36
  OneClickClient: () => OneClickClient,
37
37
  PaymentModal: () => PaymentModal,
38
+ PayoutClient: () => PayoutClient,
38
39
  PrivacyFeatures: () => PrivacyFeatures,
39
40
  REACT_NATIVE_EXAMPLE: () => REACT_NATIVE_EXAMPLE,
40
41
  REST_API: () => REST_API,
@@ -44,6 +45,7 @@ __export(index_exports, {
44
45
  SUPPORTED_TOKENS: () => SUPPORTED_TOKENS,
45
46
  Settlr: () => Settlr,
46
47
  SettlrProvider: () => SettlrProvider,
48
+ SubscriptionClient: () => SubscriptionClient,
47
49
  UNITY_EXAMPLE: () => UNITY_EXAMPLE,
48
50
  USDC_MINT_DEVNET: () => USDC_MINT_DEVNET,
49
51
  USDC_MINT_MAINNET: () => USDC_MINT_MAINNET,
@@ -52,6 +54,8 @@ __export(index_exports, {
52
54
  buildAllowanceRemainingAccounts: () => buildAllowanceRemainingAccounts,
53
55
  buildPrivateReceiptAccounts: () => buildPrivateReceiptAccounts,
54
56
  createOneClickClient: () => createOneClickClient,
57
+ createPayoutClient: () => createPayoutClient,
58
+ createSubscriptionClient: () => createSubscriptionClient,
55
59
  createWebhookHandler: () => createWebhookHandler,
56
60
  encryptAmount: () => encryptAmount,
57
61
  findAllowancePda: () => findAllowancePda,
@@ -1650,6 +1654,340 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
1650
1654
  return { startPayment };
1651
1655
  }
1652
1656
  `;
1657
+
1658
+ // src/subscriptions.ts
1659
+ var SubscriptionClient = class {
1660
+ constructor(config) {
1661
+ if (!config.apiKey) {
1662
+ throw new Error(
1663
+ "API key is required. Get one at https://settlr.dev/dashboard"
1664
+ );
1665
+ }
1666
+ this.apiKey = config.apiKey;
1667
+ this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
1668
+ this.merchantId = config.merchantId;
1669
+ this.merchantWallet = config.merchantWallet;
1670
+ }
1671
+ async fetch(path, options = {}) {
1672
+ const url = `${this.baseUrl}${path}`;
1673
+ const res = await fetch(url, {
1674
+ ...options,
1675
+ headers: {
1676
+ "Content-Type": "application/json",
1677
+ "X-API-Key": this.apiKey,
1678
+ ...options.headers
1679
+ }
1680
+ });
1681
+ const data = await res.json();
1682
+ if (!res.ok) {
1683
+ throw new Error(
1684
+ data.error || `API error: ${res.status}`
1685
+ );
1686
+ }
1687
+ return data;
1688
+ }
1689
+ /**
1690
+ * Resolve merchant ID from API key
1691
+ */
1692
+ async ensureMerchantId() {
1693
+ if (this.merchantId) return this.merchantId;
1694
+ const data = await this.fetch("/api/sdk/validate", {
1695
+ method: "POST",
1696
+ body: JSON.stringify({})
1697
+ });
1698
+ this.merchantId = data.merchantId;
1699
+ if (data.merchantWallet && !this.merchantWallet) {
1700
+ this.merchantWallet = data.merchantWallet;
1701
+ }
1702
+ return this.merchantId;
1703
+ }
1704
+ // ═══════════════════════════════════════
1705
+ // PLANS
1706
+ // ═══════════════════════════════════════
1707
+ /**
1708
+ * Create a subscription plan
1709
+ */
1710
+ async createPlan(options) {
1711
+ const merchantId = await this.ensureMerchantId();
1712
+ const data = await this.fetch(
1713
+ "/api/subscriptions/plans",
1714
+ {
1715
+ method: "POST",
1716
+ body: JSON.stringify({
1717
+ merchantId,
1718
+ name: options.name,
1719
+ description: options.description,
1720
+ amount: options.amount,
1721
+ interval: options.interval,
1722
+ intervalCount: options.intervalCount || 1,
1723
+ trialDays: options.trialDays || 0,
1724
+ features: options.features || []
1725
+ })
1726
+ }
1727
+ );
1728
+ return data.plan;
1729
+ }
1730
+ /**
1731
+ * List all plans for the merchant
1732
+ */
1733
+ async listPlans() {
1734
+ const merchantId = await this.ensureMerchantId();
1735
+ const data = await this.fetch(
1736
+ `/api/subscriptions/plans?merchantId=${merchantId}`
1737
+ );
1738
+ return data.plans;
1739
+ }
1740
+ /**
1741
+ * Update a plan
1742
+ */
1743
+ async updatePlan(planId, options) {
1744
+ const data = await this.fetch(
1745
+ `/api/subscriptions/plans/${planId}`,
1746
+ {
1747
+ method: "PUT",
1748
+ body: JSON.stringify(options)
1749
+ }
1750
+ );
1751
+ return data.plan;
1752
+ }
1753
+ /**
1754
+ * Deactivate a plan (stops new subscriptions)
1755
+ */
1756
+ async deactivatePlan(planId) {
1757
+ await this.updatePlan(planId, { active: false });
1758
+ }
1759
+ // ═══════════════════════════════════════
1760
+ // SUBSCRIPTIONS
1761
+ // ═══════════════════════════════════════
1762
+ /**
1763
+ * Subscribe a customer to a plan
1764
+ */
1765
+ async subscribe(options) {
1766
+ const data = await this.fetch("/api/subscriptions", {
1767
+ method: "POST",
1768
+ body: JSON.stringify({
1769
+ action: "subscribe",
1770
+ planId: options.planId,
1771
+ customerWallet: options.customerWallet,
1772
+ merchantWallet: options.merchantWallet || this.merchantWallet,
1773
+ customerEmail: options.customerEmail,
1774
+ metadata: options.metadata
1775
+ })
1776
+ });
1777
+ return data;
1778
+ }
1779
+ /**
1780
+ * List subscriptions
1781
+ */
1782
+ async listSubscriptions(options) {
1783
+ const merchantId = await this.ensureMerchantId();
1784
+ const params = new URLSearchParams({ merchantId });
1785
+ if (options?.status) params.set("status", options.status);
1786
+ if (options?.customerWallet)
1787
+ params.set("customer", options.customerWallet);
1788
+ if (options?.planId) params.set("planId", options.planId);
1789
+ const data = await this.fetch(
1790
+ `/api/subscriptions?${params.toString()}`
1791
+ );
1792
+ return data.subscriptions;
1793
+ }
1794
+ /**
1795
+ * Get subscription details including payment history
1796
+ */
1797
+ async getSubscription(subscriptionId) {
1798
+ const data = await this.fetch(`/api/subscriptions/${subscriptionId}`);
1799
+ return {
1800
+ ...data.subscription,
1801
+ payments: data.payments
1802
+ };
1803
+ }
1804
+ /**
1805
+ * Cancel a subscription
1806
+ * @param immediately - If true, cancels now. If false (default), cancels at end of billing period.
1807
+ */
1808
+ async cancel(subscriptionId, immediately = false) {
1809
+ return this.fetch("/api/subscriptions", {
1810
+ method: "POST",
1811
+ body: JSON.stringify({
1812
+ action: "cancel",
1813
+ subscriptionId,
1814
+ immediately
1815
+ })
1816
+ });
1817
+ }
1818
+ /**
1819
+ * Pause a subscription (stops billing, preserves subscription)
1820
+ */
1821
+ async pause(subscriptionId) {
1822
+ return this.fetch("/api/subscriptions", {
1823
+ method: "POST",
1824
+ body: JSON.stringify({
1825
+ action: "pause",
1826
+ subscriptionId
1827
+ })
1828
+ });
1829
+ }
1830
+ /**
1831
+ * Resume a paused subscription
1832
+ */
1833
+ async resume(subscriptionId) {
1834
+ return this.fetch("/api/subscriptions", {
1835
+ method: "POST",
1836
+ body: JSON.stringify({
1837
+ action: "resume",
1838
+ subscriptionId
1839
+ })
1840
+ });
1841
+ }
1842
+ /**
1843
+ * Manually charge a subscription (useful for metered billing)
1844
+ */
1845
+ async charge(subscriptionId) {
1846
+ return this.fetch("/api/subscriptions", {
1847
+ method: "POST",
1848
+ body: JSON.stringify({
1849
+ action: "charge",
1850
+ subscriptionId
1851
+ })
1852
+ });
1853
+ }
1854
+ };
1855
+ function createSubscriptionClient(config) {
1856
+ return new SubscriptionClient(config);
1857
+ }
1858
+
1859
+ // src/payouts.ts
1860
+ var PayoutClient = class {
1861
+ constructor(config) {
1862
+ if (!config.apiKey) {
1863
+ throw new Error(
1864
+ "API key is required. Get one at https://settlr.dev/dashboard"
1865
+ );
1866
+ }
1867
+ this.apiKey = config.apiKey;
1868
+ this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
1869
+ }
1870
+ async fetch(path, options = {}) {
1871
+ const url = `${this.baseUrl}${path}`;
1872
+ const res = await fetch(url, {
1873
+ ...options,
1874
+ headers: {
1875
+ "Content-Type": "application/json",
1876
+ "X-API-Key": this.apiKey,
1877
+ ...options.headers
1878
+ }
1879
+ });
1880
+ const data = await res.json();
1881
+ if (!res.ok) {
1882
+ throw new Error(
1883
+ data.error || `Payout API error: ${res.status}`
1884
+ );
1885
+ }
1886
+ return data;
1887
+ }
1888
+ // -----------------------------------------------------------------------
1889
+ // Create a single payout
1890
+ // -----------------------------------------------------------------------
1891
+ /**
1892
+ * Send a payout to a recipient by email.
1893
+ * They'll receive an email with a claim link — no wallet or bank details needed.
1894
+ *
1895
+ * @example
1896
+ * ```typescript
1897
+ * const payout = await payouts.create({
1898
+ * email: 'alice@example.com',
1899
+ * amount: 250.00,
1900
+ * memo: 'March data labeling — 500 tasks',
1901
+ * });
1902
+ * console.log(payout.id); // "po_abc123"
1903
+ * console.log(payout.status); // "sent"
1904
+ * console.log(payout.claimUrl); // "https://settlr.dev/claim/..."
1905
+ * ```
1906
+ */
1907
+ async create(options) {
1908
+ if (!options.email || !options.email.includes("@")) {
1909
+ throw new Error("Valid email address is required");
1910
+ }
1911
+ if (!options.amount || options.amount <= 0) {
1912
+ throw new Error("Amount must be a positive number");
1913
+ }
1914
+ return this.fetch("/api/payouts", {
1915
+ method: "POST",
1916
+ body: JSON.stringify({
1917
+ email: options.email,
1918
+ amount: options.amount,
1919
+ currency: options.currency || "USDC",
1920
+ memo: options.memo,
1921
+ metadata: options.metadata
1922
+ })
1923
+ });
1924
+ }
1925
+ // -----------------------------------------------------------------------
1926
+ // Create batch payouts
1927
+ // -----------------------------------------------------------------------
1928
+ /**
1929
+ * Send multiple payouts at once. Each recipient gets their own email.
1930
+ *
1931
+ * @example
1932
+ * ```typescript
1933
+ * const batch = await payouts.createBatch([
1934
+ * { email: 'alice@example.com', amount: 250.00, memo: 'March' },
1935
+ * { email: 'bob@example.com', amount: 180.00, memo: 'March' },
1936
+ * ]);
1937
+ * console.log(batch.id); // "batch_xyz"
1938
+ * console.log(batch.total); // 430.00
1939
+ * ```
1940
+ */
1941
+ async createBatch(payoutsList) {
1942
+ if (!Array.isArray(payoutsList) || payoutsList.length === 0) {
1943
+ throw new Error("Payouts list must be a non-empty array");
1944
+ }
1945
+ return this.fetch("/api/payouts/batch", {
1946
+ method: "POST",
1947
+ body: JSON.stringify({ payouts: payoutsList })
1948
+ });
1949
+ }
1950
+ // -----------------------------------------------------------------------
1951
+ // Get a single payout
1952
+ // -----------------------------------------------------------------------
1953
+ /**
1954
+ * Get a payout by ID.
1955
+ *
1956
+ * @example
1957
+ * ```typescript
1958
+ * const payout = await payouts.get('po_abc123');
1959
+ * console.log(payout.status); // "claimed"
1960
+ * console.log(payout.claimedAt); // "2024-03-15T14:30:00Z"
1961
+ * ```
1962
+ */
1963
+ async get(id) {
1964
+ if (!id) throw new Error("Payout ID is required");
1965
+ return this.fetch(`/api/payouts/${encodeURIComponent(id)}`);
1966
+ }
1967
+ // -----------------------------------------------------------------------
1968
+ // List payouts
1969
+ // -----------------------------------------------------------------------
1970
+ /**
1971
+ * List payouts for the authenticated merchant.
1972
+ *
1973
+ * @example
1974
+ * ```typescript
1975
+ * const result = await payouts.list({ status: 'claimed', limit: 50 });
1976
+ * result.data.forEach(p => console.log(p.email, p.amount, p.status));
1977
+ * ```
1978
+ */
1979
+ async list(options) {
1980
+ const params = new URLSearchParams();
1981
+ if (options?.status) params.set("status", options.status);
1982
+ if (options?.limit) params.set("limit", options.limit.toString());
1983
+ if (options?.offset) params.set("offset", options.offset.toString());
1984
+ const qs = params.toString();
1985
+ return this.fetch(`/api/payouts${qs ? `?${qs}` : ""}`);
1986
+ }
1987
+ };
1988
+ function createPayoutClient(config) {
1989
+ return new PayoutClient(config);
1990
+ }
1653
1991
  // Annotate the CommonJS export names for ESM import in node:
1654
1992
  0 && (module.exports = {
1655
1993
  BuyButton,
@@ -1657,6 +1995,7 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
1657
1995
  INCO_LIGHTNING_PROGRAM_ID,
1658
1996
  OneClickClient,
1659
1997
  PaymentModal,
1998
+ PayoutClient,
1660
1999
  PrivacyFeatures,
1661
2000
  REACT_NATIVE_EXAMPLE,
1662
2001
  REST_API,
@@ -1666,6 +2005,7 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
1666
2005
  SUPPORTED_TOKENS,
1667
2006
  Settlr,
1668
2007
  SettlrProvider,
2008
+ SubscriptionClient,
1669
2009
  UNITY_EXAMPLE,
1670
2010
  USDC_MINT_DEVNET,
1671
2011
  USDC_MINT_MAINNET,
@@ -1674,6 +2014,8 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
1674
2014
  buildAllowanceRemainingAccounts,
1675
2015
  buildPrivateReceiptAccounts,
1676
2016
  createOneClickClient,
2017
+ createPayoutClient,
2018
+ createSubscriptionClient,
1677
2019
  createWebhookHandler,
1678
2020
  encryptAmount,
1679
2021
  findAllowancePda,