@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.0.5-alpha.1",
3
+ "version": "0.0.5-alpha.2",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -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.