@settlr/sdk 0.6.5 → 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.mjs CHANGED
@@ -145,8 +145,13 @@ var Settlr = class {
145
145
  * Fetches merchant wallet address if not provided in config.
146
146
  */
147
147
  async validateApiKey() {
148
- if (this.validated) return;
148
+ console.log("[Settlr] validateApiKey called, validated:", this.validated, "apiBaseUrl:", this.apiBaseUrl);
149
+ if (this.validated) {
150
+ console.log("[Settlr] Already validated, skipping. merchantWallet:", this.merchantWallet?.toString(), "merchantWalletFromValidation:", this.merchantWalletFromValidation);
151
+ return;
152
+ }
149
153
  try {
154
+ console.log("[Settlr] Fetching validation from:", `${this.apiBaseUrl}/sdk/validate`);
150
155
  const response = await fetch(`${this.apiBaseUrl}/sdk/validate`, {
151
156
  method: "POST",
152
157
  headers: {
@@ -162,16 +167,19 @@ var Settlr = class {
162
167
  throw new Error(error.error || "API key validation failed");
163
168
  }
164
169
  const data = await response.json();
170
+ console.log("[Settlr] Validation response:", data);
165
171
  if (!data.valid) {
166
172
  throw new Error(data.error || "Invalid API key");
167
173
  }
168
174
  this.validated = true;
169
175
  this.merchantId = data.merchantId;
170
176
  this.tier = data.tier;
177
+ console.log("[Settlr] Setting wallet. data.merchantWallet:", data.merchantWallet, "this.merchantWallet:", this.merchantWallet?.toString());
171
178
  if (data.merchantWallet && !this.merchantWallet) {
172
179
  this.merchantWallet = new PublicKey2(data.merchantWallet);
173
180
  this.merchantWalletFromValidation = data.merchantWallet;
174
181
  this.config.merchant.walletAddress = data.merchantWallet;
182
+ console.log("[Settlr] Wallet SET! merchantWallet:", this.merchantWallet.toString(), "merchantWalletFromValidation:", this.merchantWalletFromValidation);
175
183
  }
176
184
  if (data.merchantName && !this.config.merchant.name) {
177
185
  this.config.merchant.name = data.merchantName;
@@ -212,8 +220,10 @@ var Settlr = class {
212
220
  */
213
221
  getCheckoutUrl(options) {
214
222
  const { amount, memo, orderId, successUrl, cancelUrl } = options;
223
+ console.log("[Settlr] getCheckoutUrl - config.wallet:", this.config.merchant.walletAddress, "merchantWalletFromValidation:", this.merchantWalletFromValidation, "validated:", this.validated);
215
224
  const walletAddress = this.config.merchant.walletAddress?.toString() || this.merchantWalletFromValidation;
216
225
  if (!walletAddress) {
226
+ console.error("[Settlr] No wallet address available!");
217
227
  throw new Error("Wallet address not available. Either provide walletAddress in config or call validateApiKey() first.");
218
228
  }
219
229
  const baseUrl = this.config.testMode ? SETTLR_CHECKOUT_URL.development : SETTLR_CHECKOUT_URL.production;
@@ -1586,12 +1596,347 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
1586
1596
  return { startPayment };
1587
1597
  }
1588
1598
  `;
1599
+
1600
+ // src/subscriptions.ts
1601
+ var SubscriptionClient = class {
1602
+ constructor(config) {
1603
+ if (!config.apiKey) {
1604
+ throw new Error(
1605
+ "API key is required. Get one at https://settlr.dev/dashboard"
1606
+ );
1607
+ }
1608
+ this.apiKey = config.apiKey;
1609
+ this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
1610
+ this.merchantId = config.merchantId;
1611
+ this.merchantWallet = config.merchantWallet;
1612
+ }
1613
+ async fetch(path, options = {}) {
1614
+ const url = `${this.baseUrl}${path}`;
1615
+ const res = await fetch(url, {
1616
+ ...options,
1617
+ headers: {
1618
+ "Content-Type": "application/json",
1619
+ "X-API-Key": this.apiKey,
1620
+ ...options.headers
1621
+ }
1622
+ });
1623
+ const data = await res.json();
1624
+ if (!res.ok) {
1625
+ throw new Error(
1626
+ data.error || `API error: ${res.status}`
1627
+ );
1628
+ }
1629
+ return data;
1630
+ }
1631
+ /**
1632
+ * Resolve merchant ID from API key
1633
+ */
1634
+ async ensureMerchantId() {
1635
+ if (this.merchantId) return this.merchantId;
1636
+ const data = await this.fetch("/api/sdk/validate", {
1637
+ method: "POST",
1638
+ body: JSON.stringify({})
1639
+ });
1640
+ this.merchantId = data.merchantId;
1641
+ if (data.merchantWallet && !this.merchantWallet) {
1642
+ this.merchantWallet = data.merchantWallet;
1643
+ }
1644
+ return this.merchantId;
1645
+ }
1646
+ // ═══════════════════════════════════════
1647
+ // PLANS
1648
+ // ═══════════════════════════════════════
1649
+ /**
1650
+ * Create a subscription plan
1651
+ */
1652
+ async createPlan(options) {
1653
+ const merchantId = await this.ensureMerchantId();
1654
+ const data = await this.fetch(
1655
+ "/api/subscriptions/plans",
1656
+ {
1657
+ method: "POST",
1658
+ body: JSON.stringify({
1659
+ merchantId,
1660
+ name: options.name,
1661
+ description: options.description,
1662
+ amount: options.amount,
1663
+ interval: options.interval,
1664
+ intervalCount: options.intervalCount || 1,
1665
+ trialDays: options.trialDays || 0,
1666
+ features: options.features || []
1667
+ })
1668
+ }
1669
+ );
1670
+ return data.plan;
1671
+ }
1672
+ /**
1673
+ * List all plans for the merchant
1674
+ */
1675
+ async listPlans() {
1676
+ const merchantId = await this.ensureMerchantId();
1677
+ const data = await this.fetch(
1678
+ `/api/subscriptions/plans?merchantId=${merchantId}`
1679
+ );
1680
+ return data.plans;
1681
+ }
1682
+ /**
1683
+ * Update a plan
1684
+ */
1685
+ async updatePlan(planId, options) {
1686
+ const data = await this.fetch(
1687
+ `/api/subscriptions/plans/${planId}`,
1688
+ {
1689
+ method: "PUT",
1690
+ body: JSON.stringify(options)
1691
+ }
1692
+ );
1693
+ return data.plan;
1694
+ }
1695
+ /**
1696
+ * Deactivate a plan (stops new subscriptions)
1697
+ */
1698
+ async deactivatePlan(planId) {
1699
+ await this.updatePlan(planId, { active: false });
1700
+ }
1701
+ // ═══════════════════════════════════════
1702
+ // SUBSCRIPTIONS
1703
+ // ═══════════════════════════════════════
1704
+ /**
1705
+ * Subscribe a customer to a plan
1706
+ */
1707
+ async subscribe(options) {
1708
+ const data = await this.fetch("/api/subscriptions", {
1709
+ method: "POST",
1710
+ body: JSON.stringify({
1711
+ action: "subscribe",
1712
+ planId: options.planId,
1713
+ customerWallet: options.customerWallet,
1714
+ merchantWallet: options.merchantWallet || this.merchantWallet,
1715
+ customerEmail: options.customerEmail,
1716
+ metadata: options.metadata
1717
+ })
1718
+ });
1719
+ return data;
1720
+ }
1721
+ /**
1722
+ * List subscriptions
1723
+ */
1724
+ async listSubscriptions(options) {
1725
+ const merchantId = await this.ensureMerchantId();
1726
+ const params = new URLSearchParams({ merchantId });
1727
+ if (options?.status) params.set("status", options.status);
1728
+ if (options?.customerWallet)
1729
+ params.set("customer", options.customerWallet);
1730
+ if (options?.planId) params.set("planId", options.planId);
1731
+ const data = await this.fetch(
1732
+ `/api/subscriptions?${params.toString()}`
1733
+ );
1734
+ return data.subscriptions;
1735
+ }
1736
+ /**
1737
+ * Get subscription details including payment history
1738
+ */
1739
+ async getSubscription(subscriptionId) {
1740
+ const data = await this.fetch(`/api/subscriptions/${subscriptionId}`);
1741
+ return {
1742
+ ...data.subscription,
1743
+ payments: data.payments
1744
+ };
1745
+ }
1746
+ /**
1747
+ * Cancel a subscription
1748
+ * @param immediately - If true, cancels now. If false (default), cancels at end of billing period.
1749
+ */
1750
+ async cancel(subscriptionId, immediately = false) {
1751
+ return this.fetch("/api/subscriptions", {
1752
+ method: "POST",
1753
+ body: JSON.stringify({
1754
+ action: "cancel",
1755
+ subscriptionId,
1756
+ immediately
1757
+ })
1758
+ });
1759
+ }
1760
+ /**
1761
+ * Pause a subscription (stops billing, preserves subscription)
1762
+ */
1763
+ async pause(subscriptionId) {
1764
+ return this.fetch("/api/subscriptions", {
1765
+ method: "POST",
1766
+ body: JSON.stringify({
1767
+ action: "pause",
1768
+ subscriptionId
1769
+ })
1770
+ });
1771
+ }
1772
+ /**
1773
+ * Resume a paused subscription
1774
+ */
1775
+ async resume(subscriptionId) {
1776
+ return this.fetch("/api/subscriptions", {
1777
+ method: "POST",
1778
+ body: JSON.stringify({
1779
+ action: "resume",
1780
+ subscriptionId
1781
+ })
1782
+ });
1783
+ }
1784
+ /**
1785
+ * Manually charge a subscription (useful for metered billing)
1786
+ */
1787
+ async charge(subscriptionId) {
1788
+ return this.fetch("/api/subscriptions", {
1789
+ method: "POST",
1790
+ body: JSON.stringify({
1791
+ action: "charge",
1792
+ subscriptionId
1793
+ })
1794
+ });
1795
+ }
1796
+ };
1797
+ function createSubscriptionClient(config) {
1798
+ return new SubscriptionClient(config);
1799
+ }
1800
+
1801
+ // src/payouts.ts
1802
+ var PayoutClient = class {
1803
+ constructor(config) {
1804
+ if (!config.apiKey) {
1805
+ throw new Error(
1806
+ "API key is required. Get one at https://settlr.dev/dashboard"
1807
+ );
1808
+ }
1809
+ this.apiKey = config.apiKey;
1810
+ this.baseUrl = (config.baseUrl || "https://settlr.dev").replace(/\/$/, "");
1811
+ }
1812
+ async fetch(path, options = {}) {
1813
+ const url = `${this.baseUrl}${path}`;
1814
+ const res = await fetch(url, {
1815
+ ...options,
1816
+ headers: {
1817
+ "Content-Type": "application/json",
1818
+ "X-API-Key": this.apiKey,
1819
+ ...options.headers
1820
+ }
1821
+ });
1822
+ const data = await res.json();
1823
+ if (!res.ok) {
1824
+ throw new Error(
1825
+ data.error || `Payout API error: ${res.status}`
1826
+ );
1827
+ }
1828
+ return data;
1829
+ }
1830
+ // -----------------------------------------------------------------------
1831
+ // Create a single payout
1832
+ // -----------------------------------------------------------------------
1833
+ /**
1834
+ * Send a payout to a recipient by email.
1835
+ * They'll receive an email with a claim link — no wallet or bank details needed.
1836
+ *
1837
+ * @example
1838
+ * ```typescript
1839
+ * const payout = await payouts.create({
1840
+ * email: 'alice@example.com',
1841
+ * amount: 250.00,
1842
+ * memo: 'March data labeling — 500 tasks',
1843
+ * });
1844
+ * console.log(payout.id); // "po_abc123"
1845
+ * console.log(payout.status); // "sent"
1846
+ * console.log(payout.claimUrl); // "https://settlr.dev/claim/..."
1847
+ * ```
1848
+ */
1849
+ async create(options) {
1850
+ if (!options.email || !options.email.includes("@")) {
1851
+ throw new Error("Valid email address is required");
1852
+ }
1853
+ if (!options.amount || options.amount <= 0) {
1854
+ throw new Error("Amount must be a positive number");
1855
+ }
1856
+ return this.fetch("/api/payouts", {
1857
+ method: "POST",
1858
+ body: JSON.stringify({
1859
+ email: options.email,
1860
+ amount: options.amount,
1861
+ currency: options.currency || "USDC",
1862
+ memo: options.memo,
1863
+ metadata: options.metadata
1864
+ })
1865
+ });
1866
+ }
1867
+ // -----------------------------------------------------------------------
1868
+ // Create batch payouts
1869
+ // -----------------------------------------------------------------------
1870
+ /**
1871
+ * Send multiple payouts at once. Each recipient gets their own email.
1872
+ *
1873
+ * @example
1874
+ * ```typescript
1875
+ * const batch = await payouts.createBatch([
1876
+ * { email: 'alice@example.com', amount: 250.00, memo: 'March' },
1877
+ * { email: 'bob@example.com', amount: 180.00, memo: 'March' },
1878
+ * ]);
1879
+ * console.log(batch.id); // "batch_xyz"
1880
+ * console.log(batch.total); // 430.00
1881
+ * ```
1882
+ */
1883
+ async createBatch(payoutsList) {
1884
+ if (!Array.isArray(payoutsList) || payoutsList.length === 0) {
1885
+ throw new Error("Payouts list must be a non-empty array");
1886
+ }
1887
+ return this.fetch("/api/payouts/batch", {
1888
+ method: "POST",
1889
+ body: JSON.stringify({ payouts: payoutsList })
1890
+ });
1891
+ }
1892
+ // -----------------------------------------------------------------------
1893
+ // Get a single payout
1894
+ // -----------------------------------------------------------------------
1895
+ /**
1896
+ * Get a payout by ID.
1897
+ *
1898
+ * @example
1899
+ * ```typescript
1900
+ * const payout = await payouts.get('po_abc123');
1901
+ * console.log(payout.status); // "claimed"
1902
+ * console.log(payout.claimedAt); // "2024-03-15T14:30:00Z"
1903
+ * ```
1904
+ */
1905
+ async get(id) {
1906
+ if (!id) throw new Error("Payout ID is required");
1907
+ return this.fetch(`/api/payouts/${encodeURIComponent(id)}`);
1908
+ }
1909
+ // -----------------------------------------------------------------------
1910
+ // List payouts
1911
+ // -----------------------------------------------------------------------
1912
+ /**
1913
+ * List payouts for the authenticated merchant.
1914
+ *
1915
+ * @example
1916
+ * ```typescript
1917
+ * const result = await payouts.list({ status: 'claimed', limit: 50 });
1918
+ * result.data.forEach(p => console.log(p.email, p.amount, p.status));
1919
+ * ```
1920
+ */
1921
+ async list(options) {
1922
+ const params = new URLSearchParams();
1923
+ if (options?.status) params.set("status", options.status);
1924
+ if (options?.limit) params.set("limit", options.limit.toString());
1925
+ if (options?.offset) params.set("offset", options.offset.toString());
1926
+ const qs = params.toString();
1927
+ return this.fetch(`/api/payouts${qs ? `?${qs}` : ""}`);
1928
+ }
1929
+ };
1930
+ function createPayoutClient(config) {
1931
+ return new PayoutClient(config);
1932
+ }
1589
1933
  export {
1590
1934
  BuyButton,
1591
1935
  CheckoutWidget,
1592
1936
  INCO_LIGHTNING_PROGRAM_ID,
1593
1937
  OneClickClient,
1594
1938
  PaymentModal,
1939
+ PayoutClient,
1595
1940
  PrivacyFeatures,
1596
1941
  REACT_NATIVE_EXAMPLE,
1597
1942
  REST_API,
@@ -1601,6 +1946,7 @@ export {
1601
1946
  SUPPORTED_TOKENS,
1602
1947
  Settlr,
1603
1948
  SettlrProvider,
1949
+ SubscriptionClient,
1604
1950
  UNITY_EXAMPLE,
1605
1951
  USDC_MINT_DEVNET,
1606
1952
  USDC_MINT_MAINNET,
@@ -1609,6 +1955,8 @@ export {
1609
1955
  buildAllowanceRemainingAccounts,
1610
1956
  buildPrivateReceiptAccounts,
1611
1957
  createOneClickClient,
1958
+ createPayoutClient,
1959
+ createSubscriptionClient,
1612
1960
  createWebhookHandler,
1613
1961
  encryptAmount,
1614
1962
  findAllowancePda,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@settlr/sdk",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
4
4
  "description": "Settlr SDK - Accept Solana USDC payments with privacy. Email checkout, gasless transactions, FHE-encrypted receipts. Private on-chain, compliant off-chain.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",