@rotateprotocol/sdk 1.0.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 +453 -0
- package/dist/catalog.d.ts +112 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +210 -0
- package/dist/catalog.js.map +1 -0
- package/dist/components/CheckoutForm.d.ts +86 -0
- package/dist/components/CheckoutForm.d.ts.map +1 -0
- package/dist/components/CheckoutForm.js +332 -0
- package/dist/components/CheckoutForm.js.map +1 -0
- package/dist/components/HostedCheckout.d.ts +57 -0
- package/dist/components/HostedCheckout.d.ts.map +1 -0
- package/dist/components/HostedCheckout.js +414 -0
- package/dist/components/HostedCheckout.js.map +1 -0
- package/dist/components/PaymentButton.d.ts +80 -0
- package/dist/components/PaymentButton.d.ts.map +1 -0
- package/dist/components/PaymentButton.js +210 -0
- package/dist/components/PaymentButton.js.map +1 -0
- package/dist/components/RotateProvider.d.ts +115 -0
- package/dist/components/RotateProvider.d.ts.map +1 -0
- package/dist/components/RotateProvider.js +264 -0
- package/dist/components/RotateProvider.js.map +1 -0
- package/dist/components/index.d.ts +17 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +27 -0
- package/dist/components/index.js.map +1 -0
- package/dist/embed.d.ts +85 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +313 -0
- package/dist/embed.js.map +1 -0
- package/dist/hooks.d.ts +156 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +280 -0
- package/dist/hooks.js.map +1 -0
- package/dist/idl/rotate_connect.json +2572 -0
- package/dist/index.d.ts +505 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1197 -0
- package/dist/index.js.map +1 -0
- package/dist/marketplace.d.ts +257 -0
- package/dist/marketplace.d.ts.map +1 -0
- package/dist/marketplace.js +433 -0
- package/dist/marketplace.js.map +1 -0
- package/dist/platform.d.ts +234 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +268 -0
- package/dist/platform.js.map +1 -0
- package/dist/react.d.ts +140 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +429 -0
- package/dist/react.js.map +1 -0
- package/dist/store.d.ts +213 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +404 -0
- package/dist/store.js.map +1 -0
- package/dist/webhooks.d.ts +149 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +371 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +114 -0
- package/src/catalog.ts +299 -0
- package/src/components/CheckoutForm.tsx +608 -0
- package/src/components/HostedCheckout.tsx +675 -0
- package/src/components/PaymentButton.tsx +348 -0
- package/src/components/RotateProvider.tsx +370 -0
- package/src/components/index.ts +26 -0
- package/src/embed.ts +408 -0
- package/src/hooks.ts +518 -0
- package/src/idl/rotate_connect.json +2572 -0
- package/src/index.ts +1538 -0
- package/src/marketplace.ts +642 -0
- package/src/platform.ts +403 -0
- package/src/react.ts +459 -0
- package/src/store.ts +577 -0
- package/src/webhooks.ts +506 -0
package/src/react.ts
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rotate Protocol React Hooks
|
|
3
|
+
*
|
|
4
|
+
* React hooks for easy integration with Solana wallet adapters.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
10
|
+
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
|
|
11
|
+
import { PublicKey } from '@solana/web3.js';
|
|
12
|
+
import RotateSDK, {
|
|
13
|
+
PaymentLink,
|
|
14
|
+
Platform,
|
|
15
|
+
Merchant,
|
|
16
|
+
Protocol,
|
|
17
|
+
calculateFees,
|
|
18
|
+
generateSampleId,
|
|
19
|
+
isValidId,
|
|
20
|
+
getLinkDescription,
|
|
21
|
+
MEMO_PROGRAM_ID,
|
|
22
|
+
Network,
|
|
23
|
+
MIN_RANDOM_ID,
|
|
24
|
+
MAX_RANDOM_ID,
|
|
25
|
+
} from './index';
|
|
26
|
+
|
|
27
|
+
// ==================== TYPES ====================
|
|
28
|
+
|
|
29
|
+
export interface UseRotateOptions {
|
|
30
|
+
network?: Network;
|
|
31
|
+
rpcEndpoint?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface PaymentStatus {
|
|
35
|
+
linkId: number;
|
|
36
|
+
status: PaymentLink['status'];
|
|
37
|
+
amountPaid: bigint;
|
|
38
|
+
amountTotal: bigint;
|
|
39
|
+
isPaid: boolean;
|
|
40
|
+
isExpired: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ==================== MAIN HOOK ====================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Main hook for Rotate Protocol
|
|
47
|
+
*/
|
|
48
|
+
export function useRotate(options: UseRotateOptions = {}) {
|
|
49
|
+
const { connection } = useConnection();
|
|
50
|
+
const wallet = useWallet();
|
|
51
|
+
|
|
52
|
+
const sdk = useMemo(() => {
|
|
53
|
+
return new RotateSDK({
|
|
54
|
+
network: options.network || 'mainnet-beta',
|
|
55
|
+
rpcEndpoint: options.rpcEndpoint,
|
|
56
|
+
});
|
|
57
|
+
}, [options.network, options.rpcEndpoint]);
|
|
58
|
+
|
|
59
|
+
const [protocol, setProtocol] = useState<Protocol | null>(null);
|
|
60
|
+
const [loading, setLoading] = useState(true);
|
|
61
|
+
const [error, setError] = useState<string | null>(null);
|
|
62
|
+
|
|
63
|
+
// Load protocol on mount
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
async function load() {
|
|
66
|
+
try {
|
|
67
|
+
const data = await sdk.getProtocol();
|
|
68
|
+
setProtocol(data);
|
|
69
|
+
} catch (e: any) {
|
|
70
|
+
setError(e.message);
|
|
71
|
+
} finally {
|
|
72
|
+
setLoading(false);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
load();
|
|
76
|
+
}, [sdk]);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
sdk,
|
|
80
|
+
protocol,
|
|
81
|
+
loading,
|
|
82
|
+
error,
|
|
83
|
+
connected: wallet.connected,
|
|
84
|
+
publicKey: wallet.publicKey,
|
|
85
|
+
signTransaction: wallet.signTransaction,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ==================== PAYMENT LINK HOOK ====================
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Hook for working with a specific payment link
|
|
93
|
+
*/
|
|
94
|
+
export function usePaymentLink(linkId: number, options: UseRotateOptions = {}) {
|
|
95
|
+
const { sdk } = useRotate(options);
|
|
96
|
+
const [link, setLink] = useState<PaymentLink | null>(null);
|
|
97
|
+
const [loading, setLoading] = useState(true);
|
|
98
|
+
const [error, setError] = useState<string | null>(null);
|
|
99
|
+
|
|
100
|
+
// Load link data
|
|
101
|
+
const refresh = useCallback(async () => {
|
|
102
|
+
setLoading(true);
|
|
103
|
+
try {
|
|
104
|
+
const data = await sdk.getPaymentLink(linkId);
|
|
105
|
+
setLink(data);
|
|
106
|
+
setError(null);
|
|
107
|
+
} catch (e: any) {
|
|
108
|
+
setError(e.message);
|
|
109
|
+
} finally {
|
|
110
|
+
setLoading(false);
|
|
111
|
+
}
|
|
112
|
+
}, [sdk, linkId]);
|
|
113
|
+
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
refresh();
|
|
116
|
+
}, [refresh]);
|
|
117
|
+
|
|
118
|
+
// Poll for updates
|
|
119
|
+
const [polling, setPolling] = useState(false);
|
|
120
|
+
const pollIntervalRef = useRef(2000);
|
|
121
|
+
|
|
122
|
+
const startPolling = useCallback((intervalMs: number = 2000) => {
|
|
123
|
+
pollIntervalRef.current = intervalMs;
|
|
124
|
+
setPolling(true);
|
|
125
|
+
}, []);
|
|
126
|
+
|
|
127
|
+
const stopPolling = useCallback(() => {
|
|
128
|
+
setPolling(false);
|
|
129
|
+
}, []);
|
|
130
|
+
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (!polling) return;
|
|
133
|
+
|
|
134
|
+
const interval = setInterval(refresh, pollIntervalRef.current);
|
|
135
|
+
return () => clearInterval(interval);
|
|
136
|
+
}, [polling, refresh]);
|
|
137
|
+
|
|
138
|
+
// Status helpers
|
|
139
|
+
const status: PaymentStatus | null = link ? {
|
|
140
|
+
linkId: link.id,
|
|
141
|
+
status: link.status,
|
|
142
|
+
amountPaid: link.amountPaid,
|
|
143
|
+
amountTotal: link.amount,
|
|
144
|
+
isPaid: link.status === 'Paid',
|
|
145
|
+
isExpired: link.expiresAt > 0 && Date.now() / 1000 > link.expiresAt,
|
|
146
|
+
} : null;
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
link,
|
|
150
|
+
status,
|
|
151
|
+
loading,
|
|
152
|
+
error,
|
|
153
|
+
refresh,
|
|
154
|
+
startPolling,
|
|
155
|
+
stopPolling,
|
|
156
|
+
isPolling: polling,
|
|
157
|
+
paymentUrl: sdk.getPaymentUrl(linkId),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ==================== MERCHANT HOOK ====================
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Hook for merchant operations
|
|
165
|
+
*/
|
|
166
|
+
export function useMerchant(merchantId: number, options: UseRotateOptions = {}) {
|
|
167
|
+
const { sdk } = useRotate(options);
|
|
168
|
+
const [merchant, setMerchant] = useState<Merchant | null>(null);
|
|
169
|
+
const [platform, setPlatform] = useState<Platform | null>(null);
|
|
170
|
+
const [loading, setLoading] = useState(true);
|
|
171
|
+
const [error, setError] = useState<string | null>(null);
|
|
172
|
+
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
async function load() {
|
|
175
|
+
try {
|
|
176
|
+
const merchantData = await sdk.getMerchant(merchantId);
|
|
177
|
+
setMerchant(merchantData);
|
|
178
|
+
|
|
179
|
+
if (merchantData) {
|
|
180
|
+
const platformData = await sdk.getPlatform(merchantData.platformId);
|
|
181
|
+
setPlatform(platformData);
|
|
182
|
+
}
|
|
183
|
+
} catch (e: any) {
|
|
184
|
+
setError(e.message);
|
|
185
|
+
} finally {
|
|
186
|
+
setLoading(false);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
load();
|
|
190
|
+
}, [sdk, merchantId]);
|
|
191
|
+
|
|
192
|
+
// Calculate fees helper
|
|
193
|
+
const getFees = useCallback((amountUsd: number) => {
|
|
194
|
+
return calculateFees(amountUsd, platform?.feeBps || 0);
|
|
195
|
+
}, [platform]);
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
merchant,
|
|
199
|
+
platform,
|
|
200
|
+
loading,
|
|
201
|
+
error,
|
|
202
|
+
getFees,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ==================== SOL PRICE HOOK ====================
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Hook for SOL price.
|
|
210
|
+
* `priceApiUrl` can be overridden to use a custom price feed (default: CoinGecko).
|
|
211
|
+
*/
|
|
212
|
+
export function useSolPrice(
|
|
213
|
+
refreshIntervalMs: number = 30000,
|
|
214
|
+
priceApiUrl: string = 'https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd'
|
|
215
|
+
) {
|
|
216
|
+
const [price, setPrice] = useState<number | null>(null);
|
|
217
|
+
const [loading, setLoading] = useState(true);
|
|
218
|
+
|
|
219
|
+
const refresh = useCallback(async () => {
|
|
220
|
+
try {
|
|
221
|
+
const response = await fetch(priceApiUrl);
|
|
222
|
+
const data = await response.json() as { solana?: { usd?: number } };
|
|
223
|
+
setPrice(data.solana?.usd || null);
|
|
224
|
+
} catch {
|
|
225
|
+
// Ignore errors
|
|
226
|
+
} finally {
|
|
227
|
+
setLoading(false);
|
|
228
|
+
}
|
|
229
|
+
}, [priceApiUrl]);
|
|
230
|
+
|
|
231
|
+
useEffect(() => {
|
|
232
|
+
refresh();
|
|
233
|
+
const interval = setInterval(refresh, refreshIntervalMs);
|
|
234
|
+
return () => clearInterval(interval);
|
|
235
|
+
}, [refresh, refreshIntervalMs]);
|
|
236
|
+
|
|
237
|
+
const usdToSol = useCallback((usd: number) => {
|
|
238
|
+
if (!price) return null;
|
|
239
|
+
return usd / price;
|
|
240
|
+
}, [price]);
|
|
241
|
+
|
|
242
|
+
const solToUsd = useCallback((sol: number) => {
|
|
243
|
+
if (!price) return null;
|
|
244
|
+
return sol * price;
|
|
245
|
+
}, [price]);
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
price,
|
|
249
|
+
loading,
|
|
250
|
+
refresh,
|
|
251
|
+
usdToSol,
|
|
252
|
+
solToUsd,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ==================== TOKEN BALANCE HOOK ====================
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Hook for token balances
|
|
260
|
+
*/
|
|
261
|
+
export function useTokenBalances(options: UseRotateOptions = {}) {
|
|
262
|
+
const { sdk } = useRotate(options);
|
|
263
|
+
const { publicKey, connected } = useWallet();
|
|
264
|
+
const { connection } = useConnection();
|
|
265
|
+
|
|
266
|
+
const [balances, setBalances] = useState<{
|
|
267
|
+
sol: number;
|
|
268
|
+
usdc: number;
|
|
269
|
+
usdt: number;
|
|
270
|
+
}>({ sol: 0, usdc: 0, usdt: 0 });
|
|
271
|
+
const [loading, setLoading] = useState(true);
|
|
272
|
+
|
|
273
|
+
const refresh = useCallback(async () => {
|
|
274
|
+
if (!publicKey) return;
|
|
275
|
+
|
|
276
|
+
setLoading(true);
|
|
277
|
+
try {
|
|
278
|
+
const [solBalance, usdcBalance, usdtBalance] = await Promise.all([
|
|
279
|
+
connection.getBalance(publicKey),
|
|
280
|
+
sdk.getTokenBalance(publicKey, 'USDC'),
|
|
281
|
+
sdk.getTokenBalance(publicKey, 'USDT'),
|
|
282
|
+
]);
|
|
283
|
+
|
|
284
|
+
setBalances({
|
|
285
|
+
sol: solBalance / 1e9,
|
|
286
|
+
usdc: usdcBalance,
|
|
287
|
+
usdt: usdtBalance,
|
|
288
|
+
});
|
|
289
|
+
} catch {
|
|
290
|
+
// Ignore errors
|
|
291
|
+
} finally {
|
|
292
|
+
setLoading(false);
|
|
293
|
+
}
|
|
294
|
+
}, [connection, publicKey, sdk]);
|
|
295
|
+
|
|
296
|
+
useEffect(() => {
|
|
297
|
+
if (connected && publicKey) {
|
|
298
|
+
refresh();
|
|
299
|
+
}
|
|
300
|
+
}, [connected, publicKey, refresh]);
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
balances,
|
|
304
|
+
loading,
|
|
305
|
+
refresh,
|
|
306
|
+
hasEnough: (amount: number, currency: 'SOL' | 'USDC' | 'USDT') => {
|
|
307
|
+
const balance = currency === 'SOL' ? balances.sol :
|
|
308
|
+
currency === 'USDC' ? balances.usdc :
|
|
309
|
+
balances.usdt;
|
|
310
|
+
return balance >= amount;
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// ==================== PAYMENT FLOW HOOK ====================
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Complete payment flow hook
|
|
319
|
+
*/
|
|
320
|
+
export function usePaymentFlow(linkId: number, options: UseRotateOptions = {}) {
|
|
321
|
+
const { sdk, connected, publicKey } = useRotate(options);
|
|
322
|
+
const { link, status, refresh, startPolling, stopPolling } = usePaymentLink(linkId, options);
|
|
323
|
+
const { price: solPrice } = useSolPrice();
|
|
324
|
+
const { balances } = useTokenBalances(options);
|
|
325
|
+
|
|
326
|
+
const [selectedCurrency, setSelectedCurrency] = useState<'SOL' | 'USDC' | 'USDT'>('USDC');
|
|
327
|
+
const [paying, setPaying] = useState(false);
|
|
328
|
+
const [paymentError, setPaymentError] = useState<string | null>(null);
|
|
329
|
+
|
|
330
|
+
// Calculate amount in selected currency, accounting for link token type
|
|
331
|
+
const amountInCurrency = useMemo(() => {
|
|
332
|
+
if (!link) return null;
|
|
333
|
+
|
|
334
|
+
// SOL-denominated links store lamports (9 decimals)
|
|
335
|
+
if (link.tokenType === 'Sol') {
|
|
336
|
+
return Number(link.amount) / 1_000_000_000;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// USD / USDC / USDT links store micro-units (6 decimals)
|
|
340
|
+
const amountUsd = Number(link.amount) / 1_000_000;
|
|
341
|
+
|
|
342
|
+
if (selectedCurrency === 'SOL' && solPrice) {
|
|
343
|
+
return amountUsd / solPrice;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// USDC/USDT are 1:1 with USD
|
|
347
|
+
return amountUsd;
|
|
348
|
+
}, [link, selectedCurrency, solPrice]);
|
|
349
|
+
|
|
350
|
+
// Check if user can pay
|
|
351
|
+
const canPay = useMemo(() => {
|
|
352
|
+
if (!connected || !link || !amountInCurrency) return false;
|
|
353
|
+
if (link.status !== 'Pending' && link.status !== 'PartiallyPaid') return false;
|
|
354
|
+
|
|
355
|
+
const balance = selectedCurrency === 'SOL' ? balances.sol :
|
|
356
|
+
selectedCurrency === 'USDC' ? balances.usdc :
|
|
357
|
+
balances.usdt;
|
|
358
|
+
|
|
359
|
+
return balance >= amountInCurrency;
|
|
360
|
+
}, [connected, link, amountInCurrency, selectedCurrency, balances]);
|
|
361
|
+
|
|
362
|
+
return {
|
|
363
|
+
link,
|
|
364
|
+
status,
|
|
365
|
+
connected,
|
|
366
|
+
publicKey,
|
|
367
|
+
selectedCurrency,
|
|
368
|
+
setSelectedCurrency,
|
|
369
|
+
amountInCurrency,
|
|
370
|
+
canPay,
|
|
371
|
+
paying,
|
|
372
|
+
paymentError,
|
|
373
|
+
refresh,
|
|
374
|
+
startPolling,
|
|
375
|
+
stopPolling,
|
|
376
|
+
balances,
|
|
377
|
+
solPrice,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ==================== PLATFORM/MERCHANT CREATION HOOK ====================
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Hook for creating platforms and merchants with random IDs
|
|
385
|
+
*/
|
|
386
|
+
export function useCreateEntities(options: UseRotateOptions = {}) {
|
|
387
|
+
const { sdk, connected, publicKey } = useRotate(options);
|
|
388
|
+
const [creating, setCreating] = useState(false);
|
|
389
|
+
const [error, setError] = useState<string | null>(null);
|
|
390
|
+
|
|
391
|
+
const createPlatform = useCallback(async (feeBps: number, wallet: PublicKey) => {
|
|
392
|
+
if (!connected) throw new Error('Wallet not connected');
|
|
393
|
+
|
|
394
|
+
setCreating(true);
|
|
395
|
+
setError(null);
|
|
396
|
+
|
|
397
|
+
try {
|
|
398
|
+
const result = await sdk.createPlatform({ feeBps, wallet });
|
|
399
|
+
return result;
|
|
400
|
+
} catch (e: any) {
|
|
401
|
+
setError(e.message);
|
|
402
|
+
throw e;
|
|
403
|
+
} finally {
|
|
404
|
+
setCreating(false);
|
|
405
|
+
}
|
|
406
|
+
}, [sdk, connected]);
|
|
407
|
+
|
|
408
|
+
const createMerchant = useCallback(async (platformId: number, wallet: PublicKey) => {
|
|
409
|
+
if (!connected) throw new Error('Wallet not connected');
|
|
410
|
+
|
|
411
|
+
setCreating(true);
|
|
412
|
+
setError(null);
|
|
413
|
+
|
|
414
|
+
try {
|
|
415
|
+
const result = await sdk.createMerchant({ platformId, wallet });
|
|
416
|
+
return result;
|
|
417
|
+
} catch (e: any) {
|
|
418
|
+
setError(e.message);
|
|
419
|
+
throw e;
|
|
420
|
+
} finally {
|
|
421
|
+
setCreating(false);
|
|
422
|
+
}
|
|
423
|
+
}, [sdk, connected]);
|
|
424
|
+
|
|
425
|
+
return {
|
|
426
|
+
createPlatform,
|
|
427
|
+
createMerchant,
|
|
428
|
+
creating,
|
|
429
|
+
error,
|
|
430
|
+
generateSampleId,
|
|
431
|
+
isValidId,
|
|
432
|
+
MIN_RANDOM_ID,
|
|
433
|
+
MAX_RANDOM_ID,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ==================== STORE & MARKETPLACE HOOKS ====================
|
|
438
|
+
|
|
439
|
+
// Re-export from hooks module for convenience
|
|
440
|
+
export { useProducts, useCart, useMarketplace, useMarketplaceCart } from './hooks';
|
|
441
|
+
export type { UseProductsReturn, UseCartReturn, UseMarketplaceReturn, UseMarketplaceCartReturn } from './hooks';
|
|
442
|
+
|
|
443
|
+
// ==================== EXPORTS ====================
|
|
444
|
+
|
|
445
|
+
export {
|
|
446
|
+
RotateSDK,
|
|
447
|
+
calculateFees,
|
|
448
|
+
generateSampleId,
|
|
449
|
+
isValidId,
|
|
450
|
+
getLinkDescription,
|
|
451
|
+
MEMO_PROGRAM_ID,
|
|
452
|
+
MIN_RANDOM_ID,
|
|
453
|
+
MAX_RANDOM_ID,
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
// Re-export store, marketplace & platform classes
|
|
457
|
+
export { RotateStore, RotateCart } from './store';
|
|
458
|
+
export { RotateMarketplace, MarketplaceCart } from './marketplace';
|
|
459
|
+
export { RotatePlatformManager } from './platform';
|