@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.d.mts +430 -2
- package/dist/index.d.ts +430 -2
- package/dist/index.js +353 -1
- package/dist/index.mjs +349 -1
- package/package.json +1 -1
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,
|
|
@@ -209,8 +213,13 @@ var Settlr = class {
|
|
|
209
213
|
* Fetches merchant wallet address if not provided in config.
|
|
210
214
|
*/
|
|
211
215
|
async validateApiKey() {
|
|
212
|
-
|
|
216
|
+
console.log("[Settlr] validateApiKey called, validated:", this.validated, "apiBaseUrl:", this.apiBaseUrl);
|
|
217
|
+
if (this.validated) {
|
|
218
|
+
console.log("[Settlr] Already validated, skipping. merchantWallet:", this.merchantWallet?.toString(), "merchantWalletFromValidation:", this.merchantWalletFromValidation);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
213
221
|
try {
|
|
222
|
+
console.log("[Settlr] Fetching validation from:", `${this.apiBaseUrl}/sdk/validate`);
|
|
214
223
|
const response = await fetch(`${this.apiBaseUrl}/sdk/validate`, {
|
|
215
224
|
method: "POST",
|
|
216
225
|
headers: {
|
|
@@ -226,16 +235,19 @@ var Settlr = class {
|
|
|
226
235
|
throw new Error(error.error || "API key validation failed");
|
|
227
236
|
}
|
|
228
237
|
const data = await response.json();
|
|
238
|
+
console.log("[Settlr] Validation response:", data);
|
|
229
239
|
if (!data.valid) {
|
|
230
240
|
throw new Error(data.error || "Invalid API key");
|
|
231
241
|
}
|
|
232
242
|
this.validated = true;
|
|
233
243
|
this.merchantId = data.merchantId;
|
|
234
244
|
this.tier = data.tier;
|
|
245
|
+
console.log("[Settlr] Setting wallet. data.merchantWallet:", data.merchantWallet, "this.merchantWallet:", this.merchantWallet?.toString());
|
|
235
246
|
if (data.merchantWallet && !this.merchantWallet) {
|
|
236
247
|
this.merchantWallet = new import_web32.PublicKey(data.merchantWallet);
|
|
237
248
|
this.merchantWalletFromValidation = data.merchantWallet;
|
|
238
249
|
this.config.merchant.walletAddress = data.merchantWallet;
|
|
250
|
+
console.log("[Settlr] Wallet SET! merchantWallet:", this.merchantWallet.toString(), "merchantWalletFromValidation:", this.merchantWalletFromValidation);
|
|
239
251
|
}
|
|
240
252
|
if (data.merchantName && !this.config.merchant.name) {
|
|
241
253
|
this.config.merchant.name = data.merchantName;
|
|
@@ -276,8 +288,10 @@ var Settlr = class {
|
|
|
276
288
|
*/
|
|
277
289
|
getCheckoutUrl(options) {
|
|
278
290
|
const { amount, memo, orderId, successUrl, cancelUrl } = options;
|
|
291
|
+
console.log("[Settlr] getCheckoutUrl - config.wallet:", this.config.merchant.walletAddress, "merchantWalletFromValidation:", this.merchantWalletFromValidation, "validated:", this.validated);
|
|
279
292
|
const walletAddress = this.config.merchant.walletAddress?.toString() || this.merchantWalletFromValidation;
|
|
280
293
|
if (!walletAddress) {
|
|
294
|
+
console.error("[Settlr] No wallet address available!");
|
|
281
295
|
throw new Error("Wallet address not available. Either provide walletAddress in config or call validateApiKey() first.");
|
|
282
296
|
}
|
|
283
297
|
const baseUrl = this.config.testMode ? SETTLR_CHECKOUT_URL.development : SETTLR_CHECKOUT_URL.production;
|
|
@@ -1640,6 +1654,340 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1640
1654
|
return { startPayment };
|
|
1641
1655
|
}
|
|
1642
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
|
+
}
|
|
1643
1991
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1644
1992
|
0 && (module.exports = {
|
|
1645
1993
|
BuyButton,
|
|
@@ -1647,6 +1995,7 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1647
1995
|
INCO_LIGHTNING_PROGRAM_ID,
|
|
1648
1996
|
OneClickClient,
|
|
1649
1997
|
PaymentModal,
|
|
1998
|
+
PayoutClient,
|
|
1650
1999
|
PrivacyFeatures,
|
|
1651
2000
|
REACT_NATIVE_EXAMPLE,
|
|
1652
2001
|
REST_API,
|
|
@@ -1656,6 +2005,7 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1656
2005
|
SUPPORTED_TOKENS,
|
|
1657
2006
|
Settlr,
|
|
1658
2007
|
SettlrProvider,
|
|
2008
|
+
SubscriptionClient,
|
|
1659
2009
|
UNITY_EXAMPLE,
|
|
1660
2010
|
USDC_MINT_DEVNET,
|
|
1661
2011
|
USDC_MINT_MAINNET,
|
|
@@ -1664,6 +2014,8 @@ export function useSettlrPayment(onSuccess: (sig: string) => void) {
|
|
|
1664
2014
|
buildAllowanceRemainingAccounts,
|
|
1665
2015
|
buildPrivateReceiptAccounts,
|
|
1666
2016
|
createOneClickClient,
|
|
2017
|
+
createPayoutClient,
|
|
2018
|
+
createSubscriptionClient,
|
|
1667
2019
|
createWebhookHandler,
|
|
1668
2020
|
encryptAmount,
|
|
1669
2021
|
findAllowancePda,
|