@b3dotfun/sdk 0.0.9-alpha.2 → 0.0.9-alpha.3
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/package.json +1 -1
- package/src/anyspend/README.md +70 -556
- package/src/anyspend/docs/components.md +292 -0
- package/src/anyspend/docs/contributing.md +448 -0
- package/src/anyspend/docs/error-handling.md +735 -0
- package/src/anyspend/docs/examples.md +707 -0
- package/src/anyspend/docs/hooks.md +465 -0
- package/src/anyspend/docs/installation.md +113 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
# Hooks API Reference
|
|
2
|
+
|
|
3
|
+
AnySpend provides a comprehensive set of React hooks for building custom payment flows and managing order lifecycles.
|
|
4
|
+
|
|
5
|
+
## Core Hooks
|
|
6
|
+
|
|
7
|
+
### `useAnyspendQuote`
|
|
8
|
+
|
|
9
|
+
Get real-time pricing information for token swaps and cross-chain transactions.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { useAnyspendQuote } from "@b3dotfun/sdk/anyspend";
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
anyspendQuote,
|
|
16
|
+
isLoadingAnyspendQuote,
|
|
17
|
+
getAnyspendQuoteError,
|
|
18
|
+
refetchAnyspendQuote
|
|
19
|
+
} = useAnyspendQuote(isMainnet, quoteRequest);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
#### Parameters
|
|
23
|
+
|
|
24
|
+
| Parameter | Type | Description |
|
|
25
|
+
|-----------|------|-------------|
|
|
26
|
+
| `isMainnet` | `boolean` | Use mainnet or testnet environment |
|
|
27
|
+
| `quoteRequest` | `QuoteRequest` | Quote configuration object |
|
|
28
|
+
|
|
29
|
+
#### QuoteRequest Interface
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
interface QuoteRequest {
|
|
33
|
+
srcChain: number; // Source chain ID
|
|
34
|
+
dstChain: number; // Destination chain ID
|
|
35
|
+
srcTokenAddress: string; // Source token contract address
|
|
36
|
+
dstTokenAddress: string; // Destination token contract address
|
|
37
|
+
type: "swap" | "custom"; // Order type
|
|
38
|
+
tradeType: "EXACT_INPUT" | "EXACT_OUTPUT";
|
|
39
|
+
amount: string; // Amount in smallest unit (wei)
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Return Values
|
|
44
|
+
|
|
45
|
+
| Property | Type | Description |
|
|
46
|
+
|----------|------|-------------|
|
|
47
|
+
| `anyspendQuote` | `QuoteResponse \| null` | Quote data with pricing and fees |
|
|
48
|
+
| `isLoadingAnyspendQuote` | `boolean` | Loading state |
|
|
49
|
+
| `getAnyspendQuoteError` | `Error \| null` | Error if quote failed |
|
|
50
|
+
| `refetchAnyspendQuote` | `() => void` | Manually refresh quote |
|
|
51
|
+
|
|
52
|
+
#### Usage Example
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
function SwapQuote() {
|
|
56
|
+
const quoteRequest = {
|
|
57
|
+
srcChain: 1, // Ethereum
|
|
58
|
+
dstChain: 8333, // B3
|
|
59
|
+
srcTokenAddress: "0xA0b86a33E6Fb6Dd9a9B3d8B5FEb2b3C8e7D9Ff1E", // USDC
|
|
60
|
+
dstTokenAddress: "0x0000000000000000000000000000000000000000", // ETH
|
|
61
|
+
type: "swap",
|
|
62
|
+
tradeType: "EXACT_INPUT",
|
|
63
|
+
amount: "1000000", // 1 USDC (6 decimals)
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } =
|
|
67
|
+
useAnyspendQuote(true, quoteRequest);
|
|
68
|
+
|
|
69
|
+
if (isLoadingAnyspendQuote) return <div>Getting best price...</div>;
|
|
70
|
+
if (getAnyspendQuoteError) return <div>Failed to get quote</div>;
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div>
|
|
74
|
+
<p>You'll receive: {anyspendQuote?.expectedOutput} ETH</p>
|
|
75
|
+
<p>Network fee: ${anyspendQuote?.networkFeeUsd}</p>
|
|
76
|
+
<p>Service fee: ${anyspendQuote?.serviceFeeUsd}</p>
|
|
77
|
+
<p>Total cost: ${anyspendQuote?.totalUsdCost}</p>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### `useAnyspendCreateOrder`
|
|
86
|
+
|
|
87
|
+
Create and execute AnySpend orders with comprehensive error handling.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { useAnyspendCreateOrder } from "@b3dotfun/sdk/anyspend";
|
|
91
|
+
|
|
92
|
+
const {
|
|
93
|
+
createOrder,
|
|
94
|
+
isCreatingOrder,
|
|
95
|
+
createOrderError
|
|
96
|
+
} = useAnyspendCreateOrder(options);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Parameters
|
|
100
|
+
|
|
101
|
+
| Parameter | Type | Description |
|
|
102
|
+
|-----------|------|-------------|
|
|
103
|
+
| `options` | `CreateOrderOptions` | Configuration object |
|
|
104
|
+
|
|
105
|
+
#### CreateOrderOptions Interface
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
interface CreateOrderOptions {
|
|
109
|
+
onSuccess?: (data: OrderResponse) => void;
|
|
110
|
+
onError?: (error: Error) => void;
|
|
111
|
+
onSettled?: () => void;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Return Values
|
|
116
|
+
|
|
117
|
+
| Property | Type | Description |
|
|
118
|
+
|----------|------|-------------|
|
|
119
|
+
| `createOrder` | `(request: CreateOrderRequest) => void` | Function to create order |
|
|
120
|
+
| `isCreatingOrder` | `boolean` | Loading state |
|
|
121
|
+
| `createOrderError` | `Error \| null` | Error if order creation failed |
|
|
122
|
+
|
|
123
|
+
#### Usage Example
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
function PaymentForm() {
|
|
127
|
+
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
|
|
128
|
+
onSuccess: (data) => {
|
|
129
|
+
console.log("Order created:", data.data.id);
|
|
130
|
+
// Redirect to payment or show success
|
|
131
|
+
router.push(`/payment/${data.data.id}`);
|
|
132
|
+
},
|
|
133
|
+
onError: (error) => {
|
|
134
|
+
console.error("Order failed:", error.message);
|
|
135
|
+
toast.error("Payment failed. Please try again.");
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const handlePayment = () => {
|
|
140
|
+
createOrder({
|
|
141
|
+
isMainnet: true,
|
|
142
|
+
recipientAddress: userWalletAddress,
|
|
143
|
+
orderType: "swap",
|
|
144
|
+
srcChain: 1,
|
|
145
|
+
dstChain: 8333,
|
|
146
|
+
srcToken: {
|
|
147
|
+
chainId: 1,
|
|
148
|
+
address: "0xA0b86a33E6Fb6Dd9a9B3d8B5FEb2b3C8e7D9Ff1E",
|
|
149
|
+
name: "USD Coin",
|
|
150
|
+
symbol: "USDC",
|
|
151
|
+
decimals: 6,
|
|
152
|
+
},
|
|
153
|
+
dstToken: {
|
|
154
|
+
chainId: 8333,
|
|
155
|
+
address: "0x0000000000000000000000000000000000000000",
|
|
156
|
+
name: "Ether",
|
|
157
|
+
symbol: "ETH",
|
|
158
|
+
decimals: 18,
|
|
159
|
+
},
|
|
160
|
+
srcAmount: "1000000", // 1 USDC
|
|
161
|
+
expectedDstAmount: "500000000000000000", // ~0.5 ETH
|
|
162
|
+
creatorAddress: userWalletAddress,
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<button
|
|
168
|
+
onClick={handlePayment}
|
|
169
|
+
disabled={isCreatingOrder}
|
|
170
|
+
>
|
|
171
|
+
{isCreatingOrder ? "Processing..." : "Pay with Crypto"}
|
|
172
|
+
</button>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### `useAnyspendOrderAndTransactions`
|
|
180
|
+
|
|
181
|
+
Monitor order status and track associated blockchain transactions in real-time.
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { useAnyspendOrderAndTransactions } from "@b3dotfun/sdk/anyspend";
|
|
185
|
+
|
|
186
|
+
const {
|
|
187
|
+
orderAndTransactions,
|
|
188
|
+
isLoadingOrderAndTransactions,
|
|
189
|
+
getOrderAndTransactionsError
|
|
190
|
+
} = useAnyspendOrderAndTransactions(isMainnet, orderId);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### Parameters
|
|
194
|
+
|
|
195
|
+
| Parameter | Type | Description |
|
|
196
|
+
|-----------|------|-------------|
|
|
197
|
+
| `isMainnet` | `boolean` | Environment selection |
|
|
198
|
+
| `orderId` | `string` | Order ID to track |
|
|
199
|
+
|
|
200
|
+
#### Return Values
|
|
201
|
+
|
|
202
|
+
| Property | Type | Description |
|
|
203
|
+
|----------|------|-------------|
|
|
204
|
+
| `orderAndTransactions` | `OrderWithTransactions \| null` | Complete order data |
|
|
205
|
+
| `isLoadingOrderAndTransactions` | `boolean` | Loading state |
|
|
206
|
+
| `getOrderAndTransactionsError` | `Error \| null` | Error if fetch failed |
|
|
207
|
+
|
|
208
|
+
#### OrderWithTransactions Interface
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface OrderWithTransactions {
|
|
212
|
+
data: {
|
|
213
|
+
order: Order; // Order details and status
|
|
214
|
+
depositTxs: Transaction[]; // User deposit transactions
|
|
215
|
+
relayTx?: Transaction; // Cross-chain relay transaction
|
|
216
|
+
executeTx?: Transaction; // Final execution transaction
|
|
217
|
+
refundTxs: Transaction[]; // Refund transactions (if any)
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Usage Example
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
function OrderTracker({ orderId }: { orderId: string }) {
|
|
226
|
+
const { orderAndTransactions, isLoadingOrderAndTransactions } =
|
|
227
|
+
useAnyspendOrderAndTransactions(true, orderId);
|
|
228
|
+
|
|
229
|
+
if (isLoadingOrderAndTransactions) {
|
|
230
|
+
return <div>Loading order status...</div>;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!orderAndTransactions) {
|
|
234
|
+
return <div>Order not found</div>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const { order, depositTxs, executeTx, refundTxs } = orderAndTransactions.data;
|
|
238
|
+
|
|
239
|
+
const getStatusMessage = (status: string) => {
|
|
240
|
+
switch (status) {
|
|
241
|
+
case "scanning_deposit_transaction":
|
|
242
|
+
return "⏳ Waiting for payment confirmation...";
|
|
243
|
+
case "relay":
|
|
244
|
+
return "🔄 Processing cross-chain transaction...";
|
|
245
|
+
case "executed":
|
|
246
|
+
return "✅ Transaction completed successfully!";
|
|
247
|
+
case "refunded":
|
|
248
|
+
return "↩️ Refund processed";
|
|
249
|
+
default:
|
|
250
|
+
return "🔄 Processing...";
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<div className="order-status">
|
|
256
|
+
<h2>Order #{orderId.slice(0, 8)}</h2>
|
|
257
|
+
<p>{getStatusMessage(order.status)}</p>
|
|
258
|
+
|
|
259
|
+
{depositTxs.length > 0 && (
|
|
260
|
+
<div>
|
|
261
|
+
<h3>Payment Transaction</h3>
|
|
262
|
+
<a
|
|
263
|
+
href={`https://etherscan.io/tx/${depositTxs[0].txHash}`}
|
|
264
|
+
target="_blank"
|
|
265
|
+
rel="noopener noreferrer"
|
|
266
|
+
>
|
|
267
|
+
View on Etherscan
|
|
268
|
+
</a>
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
|
|
272
|
+
{executeTx && (
|
|
273
|
+
<div>
|
|
274
|
+
<h3>Execution Transaction</h3>
|
|
275
|
+
<a
|
|
276
|
+
href={`https://explorer.b3.fun/tx/${executeTx.txHash}`}
|
|
277
|
+
target="_blank"
|
|
278
|
+
rel="noopener noreferrer"
|
|
279
|
+
>
|
|
280
|
+
View on B3 Explorer
|
|
281
|
+
</a>
|
|
282
|
+
</div>
|
|
283
|
+
)}
|
|
284
|
+
|
|
285
|
+
{order.errorDetails && (
|
|
286
|
+
<div className="error">
|
|
287
|
+
<strong>Error:</strong> {order.errorDetails}
|
|
288
|
+
</div>
|
|
289
|
+
)}
|
|
290
|
+
</div>
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
### `useAnyspendOrderHistory`
|
|
298
|
+
|
|
299
|
+
Retrieve paginated order history for a user address.
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
import { useAnyspendOrderHistory } from "@b3dotfun/sdk/anyspend";
|
|
303
|
+
|
|
304
|
+
const {
|
|
305
|
+
orderHistory,
|
|
306
|
+
isLoadingOrderHistory,
|
|
307
|
+
getOrderHistoryError
|
|
308
|
+
} = useAnyspendOrderHistory(isMainnet, creatorAddress, limit, offset);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
#### Parameters
|
|
312
|
+
|
|
313
|
+
| Parameter | Type | Description |
|
|
314
|
+
|-----------|------|-------------|
|
|
315
|
+
| `isMainnet` | `boolean` | Environment selection |
|
|
316
|
+
| `creatorAddress` | `string` | User wallet address |
|
|
317
|
+
| `limit` | `number` | Number of orders to fetch (max 100) |
|
|
318
|
+
| `offset` | `number` | Pagination offset |
|
|
319
|
+
|
|
320
|
+
#### Usage Example
|
|
321
|
+
|
|
322
|
+
```tsx
|
|
323
|
+
function OrderHistory({ userAddress }: { userAddress: string }) {
|
|
324
|
+
const [page, setPage] = useState(0);
|
|
325
|
+
const pageSize = 10;
|
|
326
|
+
|
|
327
|
+
const { orderHistory, isLoadingOrderHistory } = useAnyspendOrderHistory(
|
|
328
|
+
true,
|
|
329
|
+
userAddress,
|
|
330
|
+
pageSize,
|
|
331
|
+
page * pageSize
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
if (isLoadingOrderHistory) {
|
|
335
|
+
return <div>Loading order history...</div>;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return (
|
|
339
|
+
<div>
|
|
340
|
+
<h2>Your Orders</h2>
|
|
341
|
+
{orderHistory?.data.map((order) => (
|
|
342
|
+
<div key={order.id} className="order-item">
|
|
343
|
+
<p>Type: {order.type}</p>
|
|
344
|
+
<p>Status: {order.status}</p>
|
|
345
|
+
<p>Amount: {order.srcAmount} {order.srcToken.symbol}</p>
|
|
346
|
+
<p>Date: {new Date(order.createdAt).toLocaleDateString()}</p>
|
|
347
|
+
</div>
|
|
348
|
+
))}
|
|
349
|
+
|
|
350
|
+
<button
|
|
351
|
+
onClick={() => setPage(page - 1)}
|
|
352
|
+
disabled={page === 0}
|
|
353
|
+
>
|
|
354
|
+
Previous
|
|
355
|
+
</button>
|
|
356
|
+
<button
|
|
357
|
+
onClick={() => setPage(page + 1)}
|
|
358
|
+
disabled={!orderHistory?.data || orderHistory.data.length < pageSize}
|
|
359
|
+
>
|
|
360
|
+
Next
|
|
361
|
+
</button>
|
|
362
|
+
</div>
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Additional Hooks
|
|
368
|
+
|
|
369
|
+
### `useAnyspendTokens`
|
|
370
|
+
|
|
371
|
+
Get available tokens for a specific chain.
|
|
372
|
+
|
|
373
|
+
```tsx
|
|
374
|
+
const { tokens, isLoadingTokens } = useAnyspendTokens(true, 1, "USDC");
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### `useCoinbaseOnrampOptions`
|
|
378
|
+
|
|
379
|
+
Get Coinbase onramp configuration for fiat payments.
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
const { coinbaseOptions, isLoadingCoinbaseOptions } = useCoinbaseOnrampOptions();
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### `useStripeClientSecret`
|
|
386
|
+
|
|
387
|
+
Get Stripe payment intent for credit card payments.
|
|
388
|
+
|
|
389
|
+
```tsx
|
|
390
|
+
const { clientSecret, isLoadingClientSecret } = useStripeClientSecret(orderData);
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Hook Patterns
|
|
394
|
+
|
|
395
|
+
### Error Handling Pattern
|
|
396
|
+
|
|
397
|
+
```tsx
|
|
398
|
+
function PaymentComponent() {
|
|
399
|
+
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
|
|
400
|
+
onError: (error) => {
|
|
401
|
+
// Log error for debugging
|
|
402
|
+
console.error("Payment failed:", error);
|
|
403
|
+
|
|
404
|
+
// Show user-friendly message
|
|
405
|
+
switch (error.message) {
|
|
406
|
+
case "INSUFFICIENT_BALANCE":
|
|
407
|
+
toast.error("Insufficient balance. Please add funds.");
|
|
408
|
+
break;
|
|
409
|
+
case "SLIPPAGE":
|
|
410
|
+
toast.error("Price moved unfavorably. Please try again.");
|
|
411
|
+
break;
|
|
412
|
+
default:
|
|
413
|
+
toast.error("Payment failed. Please try again.");
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Component implementation...
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Loading State Pattern
|
|
423
|
+
|
|
424
|
+
```tsx
|
|
425
|
+
function SwapInterface() {
|
|
426
|
+
const { anyspendQuote, isLoadingAnyspendQuote } = useAnyspendQuote(true, quoteRequest);
|
|
427
|
+
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder();
|
|
428
|
+
|
|
429
|
+
const isLoading = isLoadingAnyspendQuote || isCreatingOrder;
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
<div>
|
|
433
|
+
{isLoading && <LoadingSpinner />}
|
|
434
|
+
{/* Rest of component */}
|
|
435
|
+
</div>
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Real-time Updates Pattern
|
|
441
|
+
|
|
442
|
+
```tsx
|
|
443
|
+
function OrderStatus({ orderId }: { orderId: string }) {
|
|
444
|
+
const { orderAndTransactions } = useAnyspendOrderAndTransactions(true, orderId);
|
|
445
|
+
|
|
446
|
+
// Auto-refresh every 5 seconds for pending orders
|
|
447
|
+
useEffect(() => {
|
|
448
|
+
if (orderAndTransactions?.data.order.status === "relay") {
|
|
449
|
+
const interval = setInterval(() => {
|
|
450
|
+
// Refetch is handled automatically by the hook
|
|
451
|
+
}, 5000);
|
|
452
|
+
|
|
453
|
+
return () => clearInterval(interval);
|
|
454
|
+
}
|
|
455
|
+
}, [orderAndTransactions?.data.order.status]);
|
|
456
|
+
|
|
457
|
+
// Component implementation...
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Next Steps
|
|
462
|
+
|
|
463
|
+
- [See Examples →](./examples.md)
|
|
464
|
+
- [Error Handling →](./error-handling.md)
|
|
465
|
+
- [Components Reference →](./components.md)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Installation & Setup
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- **Node.js** v20.15.0+
|
|
6
|
+
- **React** 18/19
|
|
7
|
+
- **TypeScript** (recommended)
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
### NPM
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @b3dotfun/sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Yarn
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
yarn add @b3dotfun/sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### PNPM
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @b3dotfun/sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Basic Setup
|
|
30
|
+
|
|
31
|
+
### 1. Provider Setup
|
|
32
|
+
|
|
33
|
+
Wrap your app with the `AnySpendProvider` to enable AnySpend functionality:
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { AnySpendProvider } from "@b3dotfun/sdk/anyspend/react";
|
|
37
|
+
import "@b3dotfun/sdk/index.css";
|
|
38
|
+
|
|
39
|
+
function App() {
|
|
40
|
+
return (
|
|
41
|
+
<AnySpendProvider>
|
|
42
|
+
{/* Your app components */}
|
|
43
|
+
</AnySpendProvider>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default App;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Environment Configuration
|
|
51
|
+
|
|
52
|
+
AnySpend automatically configures API endpoints based on the `isMainnet` parameter:
|
|
53
|
+
|
|
54
|
+
- **Mainnet**: `https://mainnet.anyspend.com`
|
|
55
|
+
- **Testnet**: `http://testnet.anyspend.com`
|
|
56
|
+
|
|
57
|
+
### 3. TypeScript Configuration (Optional but Recommended)
|
|
58
|
+
|
|
59
|
+
If you're using TypeScript, ensure your `tsconfig.json` includes:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"compilerOptions": {
|
|
64
|
+
"moduleResolution": "node",
|
|
65
|
+
"allowSyntheticDefaultImports": true,
|
|
66
|
+
"esModuleInterop": true
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Verification
|
|
72
|
+
|
|
73
|
+
Create a simple test component to verify your setup:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { AnySpendNFTButton } from "@b3dotfun/sdk/anyspend/react";
|
|
77
|
+
|
|
78
|
+
function TestComponent() {
|
|
79
|
+
const testNFT = {
|
|
80
|
+
chainId: 8333,
|
|
81
|
+
contractAddress: "0x9c275ff1634519E9B5449ec79cd939B5F900564d",
|
|
82
|
+
price: "500000000000000000",
|
|
83
|
+
priceFormatted: "0.5",
|
|
84
|
+
currency: {
|
|
85
|
+
chainId: 8333,
|
|
86
|
+
address: "0x0000000000000000000000000000000000000000",
|
|
87
|
+
name: "Ether",
|
|
88
|
+
symbol: "ETH",
|
|
89
|
+
decimals: 18,
|
|
90
|
+
},
|
|
91
|
+
name: "Test NFT",
|
|
92
|
+
description: "Testing AnySpend integration",
|
|
93
|
+
imageUrl: "https://via.placeholder.com/300",
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<AnySpendNFTButton
|
|
98
|
+
nftContract={testNFT}
|
|
99
|
+
recipientAddress="0x742d35Cc6634C0532925a3b8D07d77d9F05C4d57"
|
|
100
|
+
isMainnet={false} // Use testnet for testing
|
|
101
|
+
onSuccess={(txHash) => {
|
|
102
|
+
console.log("Test successful!", txHash);
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Next Steps
|
|
110
|
+
|
|
111
|
+
- [Explore Components →](./components.md)
|
|
112
|
+
- [Learn about Hooks →](./hooks.md)
|
|
113
|
+
- [See Examples →](./examples.md)
|