@b3dotfun/sdk 0.0.5-alpha.1 → 0.0.5-alpha.2
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 +694 -0
package/package.json
CHANGED
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
# AnySpend SDK Documentation
|
|
2
|
+
|
|
3
|
+
AnySpend is a powerful cross-chain protocol that enables seamless token swaps, NFT minting, tournament participation, and custom smart contract interactions across multiple blockchain networks. Built for developers who want to provide their users with a frictionless Web3 experience.
|
|
4
|
+
|
|
5
|
+
## 📦 Overview
|
|
6
|
+
|
|
7
|
+
AnySpend handles the complexity of cross-chain operations, gas management, and payment processing, allowing users to:
|
|
8
|
+
|
|
9
|
+
- **Cross-chain Swaps**: Swap tokens across different blockchain networks
|
|
10
|
+
- **NFT Minting**: Mint NFTs with automatic payment handling
|
|
11
|
+
- **Custom Interactions**: Execute any smart contract operations (tournaments, staking, gaming, etc.)
|
|
12
|
+
- **Fiat Onramp**: Convert fiat currency to crypto using integrated payment providers
|
|
13
|
+
- **Gasless Transactions**: Users don't need to worry about gas fees
|
|
14
|
+
|
|
15
|
+
### Key Features
|
|
16
|
+
|
|
17
|
+
- **Multi-chain Support**: Works across Ethereum, Base, B3, and other supported networks
|
|
18
|
+
- **Payment Flexibility**: Accept payments in various cryptocurrencies or fiat
|
|
19
|
+
- **Order Management**: Track transaction status in real-time
|
|
20
|
+
- **Error Recovery**: Automatic refund handling for failed transactions
|
|
21
|
+
- **React Integration**: Pre-built components for easy integration
|
|
22
|
+
- **TypeScript Support**: Full type safety and IntelliSense
|
|
23
|
+
|
|
24
|
+
## 🚀 Getting Started
|
|
25
|
+
|
|
26
|
+
### Prerequisites
|
|
27
|
+
|
|
28
|
+
- Node.js v18.0.0+
|
|
29
|
+
- React 18/19
|
|
30
|
+
- B3 Global Accounts integration (for authentication)
|
|
31
|
+
|
|
32
|
+
### Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @b3dotfun/sdk
|
|
36
|
+
# or
|
|
37
|
+
pnpm add @b3dotfun/sdk
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Basic Setup
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { B3Provider } from "@b3dotfun/sdk/global-account/react";
|
|
44
|
+
import { AnySpendProvider } from "@b3dotfun/sdk/anyspend/react";
|
|
45
|
+
import "@b3dotfun/sdk/index.css";
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
return (
|
|
49
|
+
<B3Provider environment="production" theme="light">
|
|
50
|
+
<AnySpendProvider>{/* Your app components */}</AnySpendProvider>
|
|
51
|
+
</B3Provider>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Quick Start Example
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { AnySpendNFTButton } from "@b3dotfun/sdk/anyspend/react";
|
|
60
|
+
|
|
61
|
+
function NFTMinting() {
|
|
62
|
+
const nftContract = {
|
|
63
|
+
chainId: 8333, // B3 network
|
|
64
|
+
contractAddress: "0x9c275ff1634519E9B5449ec79cd939B5F900564d",
|
|
65
|
+
price: "500000000000000000", // 0.5 ETH in wei
|
|
66
|
+
priceFormatted: "0.5",
|
|
67
|
+
currency: {
|
|
68
|
+
chainId: 8333,
|
|
69
|
+
address: "0x0000000000000000000000000000000000000000", // ETH
|
|
70
|
+
name: "Ether",
|
|
71
|
+
symbol: "ETH",
|
|
72
|
+
decimals: 18
|
|
73
|
+
},
|
|
74
|
+
name: "Cool NFT",
|
|
75
|
+
description: "A really cool NFT",
|
|
76
|
+
imageUrl: "https://example.com/nft.png"
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<AnySpendNFTButton
|
|
81
|
+
nftContract={nftContract}
|
|
82
|
+
recipientAddress="0x..." // User's wallet address
|
|
83
|
+
onSuccess={txHash => {
|
|
84
|
+
console.log("NFT minted successfully!", txHash);
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 🔐 Authentication
|
|
92
|
+
|
|
93
|
+
AnySpend requires B3 Global Accounts for user authentication. Users must be signed in before they can create orders.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { SignInWithB3, useB3 } from "@b3dotfun/sdk/global-account/react";
|
|
97
|
+
|
|
98
|
+
function AuthenticatedAnySpend() {
|
|
99
|
+
const { account, isAuthenticated } = useB3();
|
|
100
|
+
|
|
101
|
+
if (!isAuthenticated) {
|
|
102
|
+
return (
|
|
103
|
+
<SignInWithB3
|
|
104
|
+
chain={{ id: 8333, name: "B3" /* ... */ }}
|
|
105
|
+
partnerId="your-partner-id"
|
|
106
|
+
sessionKeyAddress="0x..."
|
|
107
|
+
onLoginSuccess={account => console.log("Authenticated!", account)}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return <AnySpendNFTButton nftContract={nftContract} recipientAddress={account.address} />;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 📚 API Reference
|
|
117
|
+
|
|
118
|
+
### Components
|
|
119
|
+
|
|
120
|
+
#### `<AnySpend>`
|
|
121
|
+
|
|
122
|
+
The main swap interface component for token-to-token exchanges.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
<AnySpend
|
|
126
|
+
isMainnet={true}
|
|
127
|
+
mode="modal" // or "page"
|
|
128
|
+
defaultActiveTab="crypto" // or "fiat"
|
|
129
|
+
destinationTokenAddress="0x..." // For buy mode
|
|
130
|
+
destinationTokenChainId={8333}
|
|
131
|
+
recipientAddress="0x..."
|
|
132
|
+
hideTransactionHistoryButton={false}
|
|
133
|
+
onSuccess={txHash => console.log("Swap completed", txHash)}
|
|
134
|
+
/>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Props:**
|
|
138
|
+
|
|
139
|
+
- `isMainnet?: boolean` - Whether to use mainnet or testnet (default: `true`)
|
|
140
|
+
- `mode?: "modal" | "page"` - Display mode (default: `"modal"`)
|
|
141
|
+
- `defaultActiveTab?: "crypto" | "fiat"` - Initial payment method (default: `"crypto"`)
|
|
142
|
+
- `destinationTokenAddress?: string` - For buy mode, specify the target token
|
|
143
|
+
- `destinationTokenChainId?: number` - Chain ID of the destination token
|
|
144
|
+
- `recipientAddress?: string` - Where to send the swapped tokens
|
|
145
|
+
- `hideTransactionHistoryButton?: boolean` - Hide the transaction history button
|
|
146
|
+
- `loadOrder?: string` - Load a specific order by ID
|
|
147
|
+
- `onSuccess?: (txHash?: string) => void` - Success callback
|
|
148
|
+
|
|
149
|
+
#### `<AnySpendNFTButton>`
|
|
150
|
+
|
|
151
|
+
A simple button component for NFT minting.
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
<AnySpendNFTButton
|
|
155
|
+
nftContract={{
|
|
156
|
+
chainId: 8333,
|
|
157
|
+
contractAddress: "0x...",
|
|
158
|
+
price: "1000000000000000000", // 1 ETH in wei
|
|
159
|
+
priceFormatted: "1.0",
|
|
160
|
+
currency: {
|
|
161
|
+
/* token details */
|
|
162
|
+
},
|
|
163
|
+
name: "My NFT",
|
|
164
|
+
description: "NFT description",
|
|
165
|
+
imageUrl: "https://example.com/image.png"
|
|
166
|
+
}}
|
|
167
|
+
recipientAddress="0x..."
|
|
168
|
+
isMainnet={true}
|
|
169
|
+
/>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### `<AnySpendCustom>`
|
|
173
|
+
|
|
174
|
+
For custom smart contract interactions.
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
<AnySpendCustom
|
|
178
|
+
orderType={OrderType.Custom}
|
|
179
|
+
dstChainId={8333}
|
|
180
|
+
dstToken={
|
|
181
|
+
{
|
|
182
|
+
/* token details */
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
dstAmount="1000000000000000000" // Amount in wei
|
|
186
|
+
contractAddress="0x..." // Target contract
|
|
187
|
+
encodedData="0x..." // Encoded function call
|
|
188
|
+
spenderAddress="0x..." // Optional spender
|
|
189
|
+
metadata={
|
|
190
|
+
{
|
|
191
|
+
/* custom metadata */
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
header={({ anyspendPrice, isLoadingAnyspendPrice }) => <div>Custom header content</div>}
|
|
195
|
+
onSuccess={txHash => console.log("Custom order completed", txHash)}
|
|
196
|
+
/>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
> **Note**: For specific use cases like staking, spin wheels, or other gaming mechanics, there are specialized components available (`AnySpendStakeB3`, `AnySpendBuySpin`, etc.). However, `AnySpendCustom` provides the most flexibility for any smart contract interaction.
|
|
200
|
+
|
|
201
|
+
### Hooks
|
|
202
|
+
|
|
203
|
+
#### `useAnyspendQuote`
|
|
204
|
+
|
|
205
|
+
Get pricing information for a potential order.
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
import { useAnyspendQuote, OrderType, TradeType } from "@b3dotfun/sdk/anyspend";
|
|
209
|
+
|
|
210
|
+
const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote(
|
|
211
|
+
true, // isMainnet
|
|
212
|
+
{
|
|
213
|
+
srcChain: 1, // Ethereum
|
|
214
|
+
dstChain: 8333, // B3
|
|
215
|
+
srcTokenAddress: "0x...", // USDC
|
|
216
|
+
dstTokenAddress: "0x...", // Target token
|
|
217
|
+
type: OrderType.Swap,
|
|
218
|
+
tradeType: TradeType.EXACT_INPUT,
|
|
219
|
+
amount: "1000000" // 1 USDC (6 decimals)
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### `useAnyspendCreateOrder`
|
|
225
|
+
|
|
226
|
+
Create a new AnySpend order.
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
import { useAnyspendCreateOrder, OrderType } from "@b3dotfun/sdk/anyspend";
|
|
230
|
+
|
|
231
|
+
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
|
|
232
|
+
onSuccess: data => {
|
|
233
|
+
console.log("Order created:", data.data.id);
|
|
234
|
+
},
|
|
235
|
+
onError: error => {
|
|
236
|
+
console.error("Order creation failed:", error.message);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Create order
|
|
241
|
+
createOrder({
|
|
242
|
+
isMainnet: true,
|
|
243
|
+
recipientAddress: "0x...",
|
|
244
|
+
orderType: OrderType.Swap,
|
|
245
|
+
srcChain: 1,
|
|
246
|
+
dstChain: 8333,
|
|
247
|
+
srcToken: {
|
|
248
|
+
/* source token details */
|
|
249
|
+
},
|
|
250
|
+
dstToken: {
|
|
251
|
+
/* destination token details */
|
|
252
|
+
},
|
|
253
|
+
srcAmount: "1000000",
|
|
254
|
+
expectedDstAmount: "500000000000000000",
|
|
255
|
+
creatorAddress: "0x..."
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### `useAnyspendOrderAndTransactions`
|
|
260
|
+
|
|
261
|
+
Track order status and associated transactions.
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import { useAnyspendOrderAndTransactions } from "@b3dotfun/sdk/anyspend";
|
|
265
|
+
|
|
266
|
+
const { orderAndTransactions, getOrderAndTransactionsError } = useAnyspendOrderAndTransactions(
|
|
267
|
+
true, // isMainnet
|
|
268
|
+
"order-id-here"
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
if (orderAndTransactions) {
|
|
272
|
+
const { order, depositTxs, relayTx, executeTx, refundTxs } = orderAndTransactions.data;
|
|
273
|
+
console.log("Order status:", order.status);
|
|
274
|
+
console.log("Deposit transactions:", depositTxs);
|
|
275
|
+
console.log("Execution transaction:", executeTx);
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### `useAnyspendOrderHistory`
|
|
280
|
+
|
|
281
|
+
Get order history for a user.
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
import { useAnyspendOrderHistory } from "@b3dotfun/sdk/anyspend";
|
|
285
|
+
|
|
286
|
+
const { orderHistory, isLoadingOrderHistory } = useAnyspendOrderHistory(
|
|
287
|
+
true, // isMainnet
|
|
288
|
+
"0x...", // creatorAddress
|
|
289
|
+
50, // limit
|
|
290
|
+
0 // offset
|
|
291
|
+
);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Service Functions
|
|
295
|
+
|
|
296
|
+
For advanced use cases, you can use the service layer directly:
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
import { anyspendService } from "@b3dotfun/sdk/anyspend/services";
|
|
300
|
+
|
|
301
|
+
// Get quote
|
|
302
|
+
const quote = await anyspendService.getQuote(true, {
|
|
303
|
+
srcChain: 1,
|
|
304
|
+
dstChain: 8333,
|
|
305
|
+
srcTokenAddress: "0x...",
|
|
306
|
+
dstTokenAddress: "0x...",
|
|
307
|
+
type: "swap",
|
|
308
|
+
tradeType: "exactInput",
|
|
309
|
+
amount: "1000000"
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Get token list
|
|
313
|
+
const tokens = await anyspendService.getTokenList(true, 1, "USDC");
|
|
314
|
+
|
|
315
|
+
// Create order
|
|
316
|
+
const order = await anyspendService.createOrder({
|
|
317
|
+
isMainnet: true,
|
|
318
|
+
recipientAddress: "0x...",
|
|
319
|
+
type: "swap",
|
|
320
|
+
srcChain: 1,
|
|
321
|
+
dstChain: 8333,
|
|
322
|
+
srcTokenAddress: "0x...",
|
|
323
|
+
dstTokenAddress: "0x...",
|
|
324
|
+
srcAmount: "1000000",
|
|
325
|
+
payload: {
|
|
326
|
+
/* order payload */
|
|
327
|
+
},
|
|
328
|
+
metadata: {
|
|
329
|
+
/* order metadata */
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## 🔧 Environment Configuration
|
|
335
|
+
|
|
336
|
+
### Environment Variables
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Optional: Custom AnySpend API endpoints
|
|
340
|
+
NEXT_PUBLIC_ANYSPEND_BASE_URL=https://your-custom-anyspend-api.com
|
|
341
|
+
|
|
342
|
+
# Required for B3 Global Accounts
|
|
343
|
+
NEXT_PUBLIC_GLOBAL_ACCOUNTS_PARTNER_ID=your-partner-id
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Network Configuration
|
|
347
|
+
|
|
348
|
+
AnySpend automatically configures API endpoints based on the `isMainnet` parameter:
|
|
349
|
+
|
|
350
|
+
- **Mainnet**: `https://anyspend-mainnet.up.railway.app`
|
|
351
|
+
- **Testnet**: `https://anyspend-testnet.up.railway.app`
|
|
352
|
+
|
|
353
|
+
## 💼 Common Use Cases
|
|
354
|
+
|
|
355
|
+
### 1. Cross-Chain Token Swap
|
|
356
|
+
|
|
357
|
+
```tsx
|
|
358
|
+
import { AnySpend } from "@b3dotfun/sdk/anyspend/react";
|
|
359
|
+
|
|
360
|
+
function TokenSwap() {
|
|
361
|
+
return (
|
|
362
|
+
<AnySpend
|
|
363
|
+
mode="page"
|
|
364
|
+
recipientAddress="0x..."
|
|
365
|
+
onSuccess={txHash => {
|
|
366
|
+
console.log("Swap completed:", txHash);
|
|
367
|
+
// Redirect user or show success message
|
|
368
|
+
}}
|
|
369
|
+
/>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### 2. NFT Marketplace Integration
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
import { AnySpendNFT } from "@b3dotfun/sdk/anyspend/react";
|
|
378
|
+
|
|
379
|
+
function NFTCard({ nft }) {
|
|
380
|
+
return (
|
|
381
|
+
<div className="nft-card">
|
|
382
|
+
<img src={nft.imageUrl} alt={nft.name} />
|
|
383
|
+
<h3>{nft.name}</h3>
|
|
384
|
+
<p>{nft.description}</p>
|
|
385
|
+
<AnySpendNFT
|
|
386
|
+
nftContract={nft}
|
|
387
|
+
recipientAddress={userAddress}
|
|
388
|
+
onSuccess={txHash => {
|
|
389
|
+
// Update UI to show NFT as owned
|
|
390
|
+
updateNFTOwnership(nft.id, userAddress);
|
|
391
|
+
}}
|
|
392
|
+
/>
|
|
393
|
+
</div>
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### 3. Custom Contract Interaction - Staking Example
|
|
399
|
+
|
|
400
|
+
```tsx
|
|
401
|
+
import { AnySpendCustom, OrderType } from "@b3dotfun/sdk/anyspend/react";
|
|
402
|
+
|
|
403
|
+
function StakingInterface({ stakingContract }) {
|
|
404
|
+
return (
|
|
405
|
+
<AnySpendCustom
|
|
406
|
+
orderType={OrderType.Custom}
|
|
407
|
+
dstChainId={stakingContract.chainId}
|
|
408
|
+
dstToken={stakingContract.stakingToken}
|
|
409
|
+
dstAmount={stakingContract.stakeAmount}
|
|
410
|
+
contractAddress={stakingContract.contractAddress}
|
|
411
|
+
encodedData={stakingContract.stakeCalldata} // encoded stake() function call
|
|
412
|
+
metadata={{
|
|
413
|
+
action: "stake",
|
|
414
|
+
staking: {
|
|
415
|
+
contractAddress: stakingContract.contractAddress,
|
|
416
|
+
amount: stakingContract.stakeAmount,
|
|
417
|
+
duration: stakingContract.duration
|
|
418
|
+
}
|
|
419
|
+
}}
|
|
420
|
+
header={({ anyspendPrice }) => (
|
|
421
|
+
<div className="staking-header">
|
|
422
|
+
<h2>Stake {stakingContract.stakingToken.symbol}</h2>
|
|
423
|
+
<p>
|
|
424
|
+
Amount: {stakingContract.stakeAmountFormatted} {stakingContract.stakingToken.symbol}
|
|
425
|
+
</p>
|
|
426
|
+
<p>Duration: {stakingContract.duration} days</p>
|
|
427
|
+
</div>
|
|
428
|
+
)}
|
|
429
|
+
onSuccess={txHash => {
|
|
430
|
+
console.log("Staking completed:", txHash);
|
|
431
|
+
// Update UI to show staked amount
|
|
432
|
+
}}
|
|
433
|
+
/>
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### 4. Fiat to Crypto Onramp
|
|
439
|
+
|
|
440
|
+
```tsx
|
|
441
|
+
import { AnySpend } from "@b3dotfun/sdk/anyspend/react";
|
|
442
|
+
|
|
443
|
+
function FiatOnramp() {
|
|
444
|
+
return (
|
|
445
|
+
<AnySpend
|
|
446
|
+
defaultActiveTab="fiat"
|
|
447
|
+
destinationTokenAddress="0x..." // Target token to buy
|
|
448
|
+
destinationTokenChainId={8333}
|
|
449
|
+
recipientAddress="0x..."
|
|
450
|
+
onSuccess={txHash => {
|
|
451
|
+
console.log("Fiat purchase completed:", txHash);
|
|
452
|
+
}}
|
|
453
|
+
/>
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## ⚠️ Error Handling
|
|
459
|
+
|
|
460
|
+
### Order Status Types
|
|
461
|
+
|
|
462
|
+
AnySpend orders go through various states:
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
enum OrderStatus {
|
|
466
|
+
// Preparation
|
|
467
|
+
ScanningDepositTransaction = "scanning_deposit_transaction",
|
|
468
|
+
WaitingStripePayment = "waiting_stripe_payment",
|
|
469
|
+
ObtainToken = "obtain_token",
|
|
470
|
+
|
|
471
|
+
// Execution
|
|
472
|
+
SendingTokenFromVault = "sending_token_from_vault",
|
|
473
|
+
Relay = "relay",
|
|
474
|
+
Executed = "executed",
|
|
475
|
+
|
|
476
|
+
// Failure/Refund
|
|
477
|
+
ObtainFailed = "obtain_failed",
|
|
478
|
+
Expired = "expired",
|
|
479
|
+
Refunding = "refunding",
|
|
480
|
+
Refunded = "refunded",
|
|
481
|
+
Failure = "failure"
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Common Error Codes
|
|
486
|
+
|
|
487
|
+
| Error Code | Description | Recovery Strategy |
|
|
488
|
+
| ------------------------- | --------------------------------- | ------------------------------------ |
|
|
489
|
+
| `SLIPPAGE` | Price movement exceeded tolerance | Retry with higher slippage tolerance |
|
|
490
|
+
| `INSUFFICIENT_BALANCE` | User doesn't have enough tokens | Request user to add funds |
|
|
491
|
+
| `NETWORK_ERROR` | RPC or network issues | Retry after a delay |
|
|
492
|
+
| `QUOTE_EXPIRED` | Price quote is no longer valid | Get a fresh quote |
|
|
493
|
+
| `AUTHENTICATION_REQUIRED` | User not signed in | Prompt user to authenticate |
|
|
494
|
+
|
|
495
|
+
### Error Handling Best Practices
|
|
496
|
+
|
|
497
|
+
```tsx
|
|
498
|
+
import { useAnyspendCreateOrder } from "@b3dotfun/sdk/anyspend";
|
|
499
|
+
|
|
500
|
+
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
|
|
501
|
+
onError: error => {
|
|
502
|
+
switch (error.message) {
|
|
503
|
+
case "SLIPPAGE":
|
|
504
|
+
toast.error("Price moved unfavorably. Please try again.");
|
|
505
|
+
break;
|
|
506
|
+
case "INSUFFICIENT_BALANCE":
|
|
507
|
+
toast.error("Insufficient balance. Please add funds to your wallet.");
|
|
508
|
+
break;
|
|
509
|
+
default:
|
|
510
|
+
toast.error("Transaction failed. Please try again or contact support.");
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Log for debugging
|
|
514
|
+
console.error("Order creation failed:", error);
|
|
515
|
+
|
|
516
|
+
// Optional: Send to error tracking service
|
|
517
|
+
// errorTracking.captureException(error);
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### Order Monitoring
|
|
523
|
+
|
|
524
|
+
```tsx
|
|
525
|
+
import { useAnyspendOrderAndTransactions, OrderStatus } from "@b3dotfun/sdk/anyspend";
|
|
526
|
+
|
|
527
|
+
function OrderTracker({ orderId }) {
|
|
528
|
+
const { orderAndTransactions } = useAnyspendOrderAndTransactions(true, orderId);
|
|
529
|
+
|
|
530
|
+
if (!orderAndTransactions) return <div>Loading...</div>;
|
|
531
|
+
|
|
532
|
+
const { order, depositTxs, executeTx, refundTxs } = orderAndTransactions.data;
|
|
533
|
+
|
|
534
|
+
const getStatusMessage = (status: OrderStatus) => {
|
|
535
|
+
switch (status) {
|
|
536
|
+
case OrderStatus.ScanningDepositTransaction:
|
|
537
|
+
return "Waiting for payment confirmation...";
|
|
538
|
+
case OrderStatus.Relay:
|
|
539
|
+
return "Processing your transaction...";
|
|
540
|
+
case OrderStatus.Executed:
|
|
541
|
+
return "Transaction completed successfully!";
|
|
542
|
+
case OrderStatus.Failure:
|
|
543
|
+
return "Transaction failed. You will be refunded automatically.";
|
|
544
|
+
case OrderStatus.Refunded:
|
|
545
|
+
return "Refund processed successfully.";
|
|
546
|
+
default:
|
|
547
|
+
return "Processing...";
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
return (
|
|
552
|
+
<div className="order-status">
|
|
553
|
+
<h3>Order Status: {order.status}</h3>
|
|
554
|
+
<p>{getStatusMessage(order.status)}</p>
|
|
555
|
+
|
|
556
|
+
{order.errorDetails && (
|
|
557
|
+
<div className="error-details">
|
|
558
|
+
<strong>Error:</strong> {order.errorDetails}
|
|
559
|
+
</div>
|
|
560
|
+
)}
|
|
561
|
+
|
|
562
|
+
{executeTx && (
|
|
563
|
+
<a href={`https://explorer.b3.fun/tx/${executeTx.txHash}`} target="_blank" rel="noopener noreferrer">
|
|
564
|
+
View Transaction
|
|
565
|
+
</a>
|
|
566
|
+
)}
|
|
567
|
+
</div>
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
## 🌐 Platform Support
|
|
573
|
+
|
|
574
|
+
| Feature | React Web | React Native |
|
|
575
|
+
| ----------------- | --------- | ------------ |
|
|
576
|
+
| Core AnySpend | ✅ | ✅ |
|
|
577
|
+
| React Components | ✅ | ✅ |
|
|
578
|
+
| Fiat Onramp | ✅ | ❌ |
|
|
579
|
+
| NFT Components | ✅ | ✅ |
|
|
580
|
+
| Service Functions | ✅ | ✅ |
|
|
581
|
+
|
|
582
|
+
## 🐛 Troubleshooting
|
|
583
|
+
|
|
584
|
+
### Common Issues
|
|
585
|
+
|
|
586
|
+
**Q: "Get rate error" appears when trying to swap**
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
A: This usually means:
|
|
590
|
+
1. Invalid token addresses
|
|
591
|
+
2. Unsupported token pair
|
|
592
|
+
3. Amount too small/large
|
|
593
|
+
4. Network connectivity issues
|
|
594
|
+
|
|
595
|
+
Check that both tokens are supported and try with a different amount.
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**Q: Order stuck in "scanning_deposit_transaction" status**
|
|
599
|
+
|
|
600
|
+
```
|
|
601
|
+
A: This means AnySpend is waiting for your deposit transaction to be confirmed.
|
|
602
|
+
Check that:
|
|
603
|
+
1. You sent the correct amount
|
|
604
|
+
2. Transaction was confirmed on-chain
|
|
605
|
+
3. You sent to the correct address
|
|
606
|
+
|
|
607
|
+
Orders will auto-refund after 30 minutes if no deposit is detected.
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Q: "Authentication required" error**
|
|
611
|
+
|
|
612
|
+
```
|
|
613
|
+
A: User needs to sign in with B3 Global Accounts first:
|
|
614
|
+
|
|
615
|
+
<SignInWithB3
|
|
616
|
+
chain={{ id: 8333, name: "B3" }}
|
|
617
|
+
partnerId="your-partner-id"
|
|
618
|
+
sessionKeyAddress="0x..."
|
|
619
|
+
/>
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Q: React Native build issues**
|
|
623
|
+
|
|
624
|
+
```
|
|
625
|
+
A: Make sure you're importing from the correct entry point:
|
|
626
|
+
|
|
627
|
+
// ✅ Correct
|
|
628
|
+
import { anyspendService } from "@b3dotfun/sdk/anyspend";
|
|
629
|
+
|
|
630
|
+
// ❌ Incorrect for React Native
|
|
631
|
+
import { AnySpend } from "@b3dotfun/sdk/anyspend/react";
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Debug Mode
|
|
635
|
+
|
|
636
|
+
Enable debug logging to troubleshoot issues:
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
// Add to your app initialization
|
|
640
|
+
localStorage.setItem("debug", "anyspend:*");
|
|
641
|
+
|
|
642
|
+
// Or in React Native
|
|
643
|
+
import { anyspendService } from "@b3dotfun/sdk/anyspend";
|
|
644
|
+
|
|
645
|
+
// Service calls will now log detailed information
|
|
646
|
+
const quote = await anyspendService.getQuote(true, quoteRequest);
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### Support Channels
|
|
650
|
+
|
|
651
|
+
- **Documentation**: [https://docs.b3.fun](https://docs.b3.fun)
|
|
652
|
+
- **GitHub Issues**: [https://github.com/b3-fun](https://github.com/b3-fun)
|
|
653
|
+
- **Discord**: [https://discord.gg/b3fun](https://discord.gg/b3fun)
|
|
654
|
+
|
|
655
|
+
## 🤝 Contributing
|
|
656
|
+
|
|
657
|
+
We welcome contributions! Here's how to get started:
|
|
658
|
+
|
|
659
|
+
1. **Fork the repository**
|
|
660
|
+
2. **Create a feature branch**: `git checkout -b feature/amazing-feature`
|
|
661
|
+
3. **Install dependencies**: `pnpm install`
|
|
662
|
+
4. **Run tests**: `pnpm test`
|
|
663
|
+
5. **Build the SDK**: `pnpm sdk:build`
|
|
664
|
+
6. **Test your changes** in the example apps
|
|
665
|
+
7. **Submit a pull request**
|
|
666
|
+
|
|
667
|
+
### Development Setup
|
|
668
|
+
|
|
669
|
+
```bash
|
|
670
|
+
# Clone the repo
|
|
671
|
+
git clone https://github.com/b3-fun/b3-monorepo.git
|
|
672
|
+
cd b3-monorepo
|
|
673
|
+
|
|
674
|
+
# Install dependencies
|
|
675
|
+
pnpm install
|
|
676
|
+
|
|
677
|
+
# Start development
|
|
678
|
+
pnpm dev
|
|
679
|
+
|
|
680
|
+
# Build the SDK
|
|
681
|
+
pnpm sdk:build
|
|
682
|
+
|
|
683
|
+
# Test in example apps
|
|
684
|
+
cd apps/login-minimal-example
|
|
685
|
+
pnpm dev
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
## 📄 License
|
|
689
|
+
|
|
690
|
+
This project is licensed under the MIT License. See the [LICENSE](../../../LICENSE) file for details.
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
**Ready to get started?** Check out our [Quick Start Guide](https://docs.b3.fun/anyspend/quickstart) or explore the [example applications](../../../apps/) in this repository.
|