@b3dotfun/sdk 0.0.40 → 0.0.41

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.
Files changed (151) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +10 -1
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +7 -3
  3. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +8 -0
  4. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +6 -3
  5. package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +5 -3
  6. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +4 -1
  7. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +9 -9
  8. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +80 -10
  9. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +2 -1
  10. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +39 -37
  11. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +8 -11
  12. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +4 -1
  13. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +23 -9
  14. package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +4 -1
  15. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +7 -6
  16. package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.d.ts +6 -0
  17. package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.js +14 -0
  18. package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
  19. package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.js +21 -0
  20. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +4 -1
  21. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +13 -5
  22. package/dist/cjs/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
  23. package/dist/cjs/anyspend/react/providers/AnyspendProvider.js +5 -3
  24. package/dist/cjs/anyspend/react/providers/index.d.ts +1 -0
  25. package/dist/cjs/anyspend/react/providers/index.js +3 -0
  26. package/dist/cjs/anyspend/types/api.d.ts +10 -0
  27. package/dist/cjs/anyspend/utils/chain.js +1 -1
  28. package/dist/cjs/bondkit/bondkitToken.d.ts +37 -2
  29. package/dist/cjs/bondkit/bondkitToken.js +268 -2
  30. package/dist/cjs/bondkit/bondkitTokenFactory.d.ts +1 -1
  31. package/dist/cjs/bondkit/bondkitTokenFactory.js +2 -2
  32. package/dist/cjs/bondkit/config.d.ts +1 -1
  33. package/dist/cjs/bondkit/config.js +5 -2
  34. package/dist/cjs/bondkit/constants.d.ts +4 -0
  35. package/dist/cjs/bondkit/constants.js +6 -1
  36. package/dist/cjs/bondkit/index.d.ts +1 -0
  37. package/dist/cjs/bondkit/index.js +4 -1
  38. package/dist/cjs/bondkit/swapService.d.ts +43 -0
  39. package/dist/cjs/bondkit/swapService.js +373 -0
  40. package/dist/cjs/bondkit/types.d.ts +10 -4
  41. package/dist/cjs/bondkit/types.js +4 -5
  42. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -3
  43. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +35 -9
  44. package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +63 -3
  45. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +35 -2
  46. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +4 -3
  47. package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -2
  48. package/dist/cjs/global-account/react/hooks/useSimBalance.js +2 -2
  49. package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +27 -22
  50. package/dist/esm/anyspend/react/components/AnySpend.d.ts +10 -1
  51. package/dist/esm/anyspend/react/components/AnySpend.js +7 -3
  52. package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +8 -0
  53. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +6 -3
  54. package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +6 -4
  55. package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +4 -1
  56. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +9 -9
  57. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +80 -10
  58. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +2 -1
  59. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +39 -37
  60. package/dist/esm/anyspend/react/components/common/OrderDetails.js +8 -11
  61. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +4 -1
  62. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +23 -9
  63. package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +4 -1
  64. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +7 -6
  65. package/dist/esm/anyspend/react/components/common/PointsDetailPanel.d.ts +6 -0
  66. package/dist/esm/anyspend/react/components/common/PointsDetailPanel.js +8 -0
  67. package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
  68. package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.js +17 -0
  69. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +4 -1
  70. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +13 -5
  71. package/dist/esm/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
  72. package/dist/esm/anyspend/react/providers/AnyspendProvider.js +5 -3
  73. package/dist/esm/anyspend/react/providers/index.d.ts +1 -0
  74. package/dist/esm/anyspend/react/providers/index.js +1 -0
  75. package/dist/esm/anyspend/types/api.d.ts +10 -0
  76. package/dist/esm/anyspend/utils/chain.js +1 -1
  77. package/dist/esm/bondkit/bondkitToken.d.ts +37 -2
  78. package/dist/esm/bondkit/bondkitToken.js +268 -2
  79. package/dist/esm/bondkit/bondkitTokenFactory.d.ts +1 -1
  80. package/dist/esm/bondkit/bondkitTokenFactory.js +2 -2
  81. package/dist/esm/bondkit/config.d.ts +1 -1
  82. package/dist/esm/bondkit/config.js +5 -2
  83. package/dist/esm/bondkit/constants.d.ts +4 -0
  84. package/dist/esm/bondkit/constants.js +5 -0
  85. package/dist/esm/bondkit/index.d.ts +1 -0
  86. package/dist/esm/bondkit/index.js +2 -0
  87. package/dist/esm/bondkit/swapService.d.ts +43 -0
  88. package/dist/esm/bondkit/swapService.js +369 -0
  89. package/dist/esm/bondkit/types.d.ts +10 -4
  90. package/dist/esm/bondkit/types.js +4 -5
  91. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -3
  92. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +36 -9
  93. package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +65 -5
  94. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +35 -2
  95. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +3 -2
  96. package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -2
  97. package/dist/esm/global-account/react/hooks/useSimBalance.js +2 -2
  98. package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +27 -22
  99. package/dist/styles/index.css +1 -1
  100. package/dist/types/anyspend/react/components/AnySpend.d.ts +10 -1
  101. package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +8 -0
  102. package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +4 -1
  103. package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +2 -1
  104. package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +4 -1
  105. package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +4 -1
  106. package/dist/types/anyspend/react/components/common/PointsDetailPanel.d.ts +6 -0
  107. package/dist/types/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
  108. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +4 -1
  109. package/dist/types/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
  110. package/dist/types/anyspend/react/providers/index.d.ts +1 -0
  111. package/dist/types/anyspend/types/api.d.ts +10 -0
  112. package/dist/types/bondkit/bondkitToken.d.ts +37 -2
  113. package/dist/types/bondkit/bondkitTokenFactory.d.ts +1 -1
  114. package/dist/types/bondkit/config.d.ts +1 -1
  115. package/dist/types/bondkit/constants.d.ts +4 -0
  116. package/dist/types/bondkit/index.d.ts +1 -0
  117. package/dist/types/bondkit/swapService.d.ts +43 -0
  118. package/dist/types/bondkit/types.d.ts +10 -4
  119. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -3
  120. package/package.json +28 -26
  121. package/src/anyspend/react/components/AnySpend.tsx +23 -0
  122. package/src/anyspend/react/components/AnyspendDepositHype.tsx +22 -0
  123. package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +7 -4
  124. package/src/anyspend/react/components/common/CryptoPaySection.tsx +13 -8
  125. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +170 -44
  126. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +63 -45
  127. package/src/anyspend/react/components/common/OrderDetails.tsx +10 -14
  128. package/src/anyspend/react/components/common/OrderTokenAmount.tsx +28 -8
  129. package/src/anyspend/react/components/common/PanelOnramp.tsx +28 -15
  130. package/src/anyspend/react/components/common/PointsDetailPanel.tsx +55 -0
  131. package/src/anyspend/react/contexts/FeatureFlagsContext.tsx +34 -0
  132. package/src/anyspend/react/hooks/useAnyspendFlow.ts +13 -5
  133. package/src/anyspend/react/providers/AnyspendProvider.tsx +11 -6
  134. package/src/anyspend/react/providers/index.ts +1 -0
  135. package/src/anyspend/types/api.ts +10 -0
  136. package/src/anyspend/types/api_req_res.ts +6 -10
  137. package/src/anyspend/utils/chain.ts +1 -1
  138. package/src/bondkit/bondkitToken.ts +323 -3
  139. package/src/bondkit/bondkitTokenFactory.ts +2 -2
  140. package/src/bondkit/config.ts +5 -2
  141. package/src/bondkit/constants.ts +7 -0
  142. package/src/bondkit/index.ts +3 -0
  143. package/src/bondkit/swapService.ts +461 -0
  144. package/src/bondkit/types.ts +12 -5
  145. package/src/global-account/react/components/B3Provider/B3Provider.tsx +51 -15
  146. package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +106 -32
  147. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +60 -5
  148. package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +4 -2
  149. package/src/global-account/react/hooks/useAuthentication.ts +1 -2
  150. package/src/global-account/react/hooks/useSimBalance.ts +2 -2
  151. package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +28 -23
@@ -0,0 +1,55 @@
1
+ import { Button, ShinyButton } from "@b3dotfun/sdk/global-account/react";
2
+ import { cn } from "@b3dotfun/sdk/shared/utils/cn";
3
+ import { ArrowDown } from "lucide-react";
4
+ import Link from "next/link";
5
+
6
+ interface PointsDetailPanelProps {
7
+ pointsAmount?: number;
8
+ onBack: () => void;
9
+ }
10
+
11
+ export function PointsDetailPanel({ pointsAmount = 0, onBack }: PointsDetailPanelProps) {
12
+ return (
13
+ <div className="mx-auto flex w-[460px] max-w-full flex-col items-center gap-4">
14
+ <div className="flex w-full items-center justify-between">
15
+ <Button
16
+ variant="ghost"
17
+ onClick={onBack}
18
+ className="text-as-primary/70 hover:text-as-primary flex items-center gap-2"
19
+ >
20
+ <ArrowDown className="h-4 w-4 rotate-90" />
21
+ Back
22
+ </Button>
23
+ </div>
24
+
25
+ <div className="flex flex-col items-center gap-4 text-center">
26
+ <h3 className="text-as-primary text-xl font-bold">Earn Points with Every Swap</h3>
27
+ <p className="text-as-primary/70 text-balance text-sm leading-relaxed">
28
+ You'll earn <span className="text-as-brand font-semibold">+{pointsAmount.toLocaleString()} points</span>{" "}
29
+ towards the{" "}
30
+ <Link href="https://anyspend.com/points" target="_blank" className="text-as-brand underline">
31
+ next AnySpend airdrop
32
+ </Link>{" "}
33
+ when you complete this transaction.
34
+ </p>
35
+ <div className="bg-as-surface-primary border-as-border-secondary mt-2 w-full rounded-lg border p-4 text-left">
36
+ <h4 className="text-as-primary mb-2 font-semibold">How it works:</h4>
37
+ <ul className="text-as-primary/70 space-y-1 text-sm">
38
+ <li>• Points are earned based on transaction volume</li>
39
+ <li>• Higher volume = more points</li>
40
+ <li>• Points contribute to future airdrops</li>
41
+ <li>• Keep swapping to maximize your rewards</li>
42
+ </ul>
43
+ </div>
44
+ <ShinyButton
45
+ accentColor={"hsl(var(--as-brand))"}
46
+ onClick={onBack}
47
+ className={cn("as-main-button !bg-as-brand relative w-full")}
48
+ textClassName={cn("text-white")}
49
+ >
50
+ Back to Swap
51
+ </ShinyButton>
52
+ </div>
53
+ </div>
54
+ );
55
+ }
@@ -0,0 +1,34 @@
1
+ "use client";
2
+
3
+ import { createContext, useContext, ReactNode } from "react";
4
+
5
+ export interface FeatureFlags {
6
+ showPoints?: boolean;
7
+ }
8
+
9
+ interface FeatureFlagsContextType {
10
+ featureFlags: FeatureFlags;
11
+ }
12
+
13
+ const FeatureFlagsContext = createContext<FeatureFlagsContextType | undefined>(undefined);
14
+
15
+ interface FeatureFlagsProviderProps {
16
+ children: ReactNode;
17
+ featureFlags?: FeatureFlags;
18
+ }
19
+
20
+ const defaultFeatureFlags: FeatureFlags = {
21
+ showPoints: false,
22
+ };
23
+
24
+ export function FeatureFlagsProvider({ children, featureFlags = defaultFeatureFlags }: FeatureFlagsProviderProps) {
25
+ return <FeatureFlagsContext.Provider value={{ featureFlags }}>{children}</FeatureFlagsContext.Provider>;
26
+ }
27
+
28
+ export function useFeatureFlags(): FeatureFlags {
29
+ const context = useContext(FeatureFlagsContext);
30
+ if (!context) {
31
+ return defaultFeatureFlags;
32
+ }
33
+ return context.featureFlags;
34
+ }
@@ -31,6 +31,7 @@ export enum PanelView {
31
31
  RECIPIENT_SELECTION,
32
32
  ORDER_DETAILS,
33
33
  LOADING,
34
+ POINTS_DETAIL,
34
35
  }
35
36
 
36
37
  interface UseAnyspendFlowProps {
@@ -244,12 +245,19 @@ export function useAnyspendFlow({
244
245
  // Handle order completion
245
246
  useEffect(() => {
246
247
  if (oat?.data?.order.status === "executed") {
247
- console.log("Order executed successfully");
248
- // just get the payload.amount if available from custompayload
249
- const amount = (oat.data.order.payload as { amount?: string })?.amount;
250
- onTransactionSuccess?.(amount);
248
+ // get the actualDstAmount if available from custompayload
249
+ const amount = (oat.data.order.payload as { actualDstAmount?: string })?.actualDstAmount;
250
+ const formattedActualDstAmount = amount
251
+ ? formatTokenAmount(BigInt(amount), oat.data.order.metadata.dstToken.decimals)
252
+ : undefined;
253
+ onTransactionSuccess?.(formattedActualDstAmount);
251
254
  }
252
- }, [oat?.data?.order.status, oat?.data?.order.payload, onTransactionSuccess]);
255
+ }, [
256
+ oat?.data?.order.status,
257
+ oat?.data?.order.payload,
258
+ onTransactionSuccess,
259
+ oat?.data?.order.metadata.dstToken.decimals,
260
+ ]);
253
261
 
254
262
  return {
255
263
  // State
@@ -3,10 +3,12 @@
3
3
  import { TooltipProvider } from "@b3dotfun/sdk/global-account/react";
4
4
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
5
5
  import { ReactNode, useState } from "react";
6
+ import { FeatureFlags, FeatureFlagsProvider } from "../contexts/FeatureFlagsContext";
6
7
  import { StripeRedirectHandler } from "./StripeRedirectHandler";
7
8
 
8
9
  interface AnyspendProviderProps {
9
10
  children: ReactNode;
11
+ featureFlags?: FeatureFlags;
10
12
  }
11
13
 
12
14
  const defaultQueryClientConfig = {
@@ -29,27 +31,30 @@ const defaultQueryClientConfig = {
29
31
  * - Safe to use at the application root
30
32
  * - Configures sensible defaults for query caching
31
33
  * - Handles Stripe payment redirects and modal state
34
+ * - Provides feature flags configuration
32
35
  *
33
36
  * @example
34
37
  * ```tsx
35
38
  * function App() {
36
39
  * return (
37
- * <AnyspendProvider>
40
+ * <AnyspendProvider featureFlags={{ showPoints: true }}>
38
41
  * <YourApp />
39
42
  * </AnyspendProvider>
40
43
  * );
41
44
  * }
42
45
  * ```
43
46
  */
44
- export const AnyspendProvider = function AnyspendProvider({ children }: AnyspendProviderProps) {
47
+ export const AnyspendProvider = function AnyspendProvider({ children, featureFlags }: AnyspendProviderProps) {
45
48
  const [queryClient] = useState(() => new QueryClient(defaultQueryClientConfig));
46
49
 
47
50
  return (
48
51
  <QueryClientProvider client={queryClient}>
49
- <TooltipProvider>
50
- <StripeRedirectHandler />
51
- {children}
52
- </TooltipProvider>
52
+ <FeatureFlagsProvider featureFlags={featureFlags}>
53
+ <TooltipProvider>
54
+ <StripeRedirectHandler />
55
+ {children}
56
+ </TooltipProvider>
57
+ </FeatureFlagsProvider>
53
58
  </QueryClientProvider>
54
59
  );
55
60
  };
@@ -1,2 +1,3 @@
1
1
  export * from "./AnyspendProvider";
2
2
  export * from "./StripeRedirectHandler";
3
+ export { useFeatureFlags, type FeatureFlags } from "../contexts/FeatureFlagsContext";
@@ -805,6 +805,16 @@ export interface paths {
805
805
  * @example 0
806
806
  */
807
807
  userBalance?: string;
808
+ /**
809
+ * @description Anyspend points that will be awarded for the order
810
+ * @example 100
811
+ */
812
+ pointsAmount?: number;
813
+ /**
814
+ * @description Multiplier applied to points that will be awarded for the order
815
+ * @example 1.5
816
+ */
817
+ pointsMultiplier?: number;
808
818
  };
809
819
  /** @example 200 */
810
820
  statusCode: number;
@@ -1,16 +1,12 @@
1
1
  import { paths } from "./api";
2
2
 
3
- export type GetOrderAndTxsResponse =
4
- paths["/orders/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"];
3
+ export type GetOrderAndTxsResponse = paths["/orders/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"];
5
4
  export type GetQuoteRequest = paths["/orders/quote"]["post"]["requestBody"]["content"]["application/json"];
6
5
  export type GetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
7
- export type GetCoinbaseOnrampOptionsResponse =
8
- paths["/onramp/coinbase/options"]["get"]["responses"]["200"]["content"]["application/json"];
6
+
7
+ export type GetCoinbaseOnrampOptionsResponse = paths["/onramp/coinbase/options"]["get"]["responses"]["200"]["content"]["application/json"];
9
8
  export type GetOrderHistoryResponse = paths["/orders"]["get"]["responses"]["200"]["content"]["application/json"];
10
- export type GetTokenListResponse =
11
- paths["/chains/{chainId}/tokens"]["get"]["responses"]["200"]["content"]["application/json"];
9
+ export type GetTokenListResponse = paths["/chains/{chainId}/tokens"]["get"]["responses"]["200"]["content"]["application/json"];
12
10
  export type CreateOrderResponse = paths["/orders"]["post"]["responses"]["200"]["content"]["application/json"];
13
- export type GetStripeSupportedResponse =
14
- paths["/onramp/stripe/supported"]["get"]["responses"]["200"]["content"]["application/json"];
15
- export type GetStripeClientSecret =
16
- paths["/stripe/clientSecret"]["get"]["responses"]["200"]["content"]["application/json"];
11
+ export type GetStripeSupportedResponse = paths["/onramp/stripe/supported"]["get"]["responses"]["200"]["content"]["application/json"];
12
+ export type GetStripeClientSecret = paths["/stripe/clientSecret"]["get"]["responses"]["200"]["content"]["application/json"];
@@ -149,7 +149,7 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
149
149
  name: bsc.name,
150
150
  logoUrl: "https://avatars.githubusercontent.com/u/45615063?s=280&v=4",
151
151
  type: ChainType.EVM,
152
- nativeRequired: parseEther("0.000025"),
152
+ nativeRequired: parseEther("0.0001"),
153
153
  canDepositNative: true,
154
154
  defaultToken: getBnbToken(),
155
155
  nativeToken: getBnbToken(),
@@ -13,13 +13,15 @@ import { privateKeyToAccount } from "viem/accounts";
13
13
  import { base } from "viem/chains";
14
14
  import { BondkitTokenABI } from "./abis";
15
15
  import { getConfig } from "./config";
16
+ import { BondkitSwapService } from "./swapService";
16
17
  import type {
17
18
  BondkitTokenInitializationConfig,
18
19
  GetTransactionHistoryOptions,
20
+ SwapQuote,
19
21
  TokenDetails,
20
- TokenStatus,
21
22
  TransactionResponse,
22
23
  } from "./types";
24
+ import { TokenStatus } from "./types";
23
25
 
24
26
  // Event ABI snippets for decoding
25
27
  const boughtEventAbi = BondkitTokenABI.find(item => item.type === "event" && item.name === "BondingCurveBuy");
@@ -53,9 +55,10 @@ export class BondkitToken {
53
55
  private walletClientInstance: WalletClient;
54
56
  private connectedProvider?: EIP1193Provider;
55
57
  private tradingToken?: Address;
58
+ private swapService?: BondkitSwapService;
56
59
 
57
- constructor(contractAddress: string, walletKey?: string) {
58
- const sdkConfig = getConfig(base.id);
60
+ constructor(contractAddress: string, walletKey?: string, rpcUrl?: string) {
61
+ const sdkConfig = getConfig(base.id, rpcUrl);
59
62
  this.chain = sdkConfig.chain;
60
63
  this.rpcUrl = sdkConfig.rpcUrl;
61
64
  this.apiEndpoint = sdkConfig.apiEndpoint;
@@ -657,6 +660,323 @@ export class BondkitToken {
657
660
  return this.executeWrite("renounceOwnership", [], options);
658
661
  }
659
662
 
663
+ // --- DEX Swap Methods ---
664
+
665
+ /**
666
+ * Get the swap service instance (lazy initialization)
667
+ */
668
+ private getSwapService(): BondkitSwapService {
669
+ if (!this.swapService) {
670
+ this.swapService = new BondkitSwapService(this.contractAddress);
671
+ }
672
+ return this.swapService;
673
+ }
674
+
675
+ /**
676
+ * Check if DEX swapping is available (token must be in Dex phase)
677
+ */
678
+ public async isSwapAvailable(): Promise<boolean | undefined> {
679
+ try {
680
+ const status = await this.currentStatus();
681
+ return status === TokenStatus.Dex;
682
+ } catch (error) {
683
+ console.warn("Error checking swap availability:", error);
684
+ return undefined;
685
+ }
686
+ }
687
+
688
+ /**
689
+ * Get swap quote for trading token → bondkit token
690
+ */
691
+ public async getSwapQuoteForBondkitToken(
692
+ amountTradingTokenIn: string,
693
+ slippageTolerance = 0.5,
694
+ ): Promise<SwapQuote | undefined> {
695
+ try {
696
+ // Check if swapping is available
697
+ const swapAvailable = await this.isSwapAvailable();
698
+ if (!swapAvailable) {
699
+ console.warn("DEX swapping not available - token must be in Dex phase");
700
+ return undefined;
701
+ }
702
+
703
+ const tradingTokenAddress = await this.getTradingTokenAddress();
704
+ if (!tradingTokenAddress) {
705
+ console.warn("Trading token address not available");
706
+ return undefined;
707
+ }
708
+
709
+ // Get token details for decimals
710
+ const [tradingTokenDecimals, bondkitTokenDecimals] = await Promise.all([
711
+ this.getTradingTokenDecimals(tradingTokenAddress),
712
+ this.decimals(),
713
+ ]);
714
+
715
+ if (tradingTokenDecimals === undefined || bondkitTokenDecimals === undefined) {
716
+ console.warn("Unable to fetch token decimals");
717
+ return undefined;
718
+ }
719
+
720
+ const swapService = this.getSwapService();
721
+ const quote = await swapService.getSwapQuote({
722
+ tokenIn: tradingTokenAddress,
723
+ tokenOut: this.contractAddress,
724
+ amountIn: amountTradingTokenIn,
725
+ tokenInDecimals: tradingTokenDecimals,
726
+ tokenOutDecimals: bondkitTokenDecimals,
727
+ slippageTolerance,
728
+ recipient: this.walletClientInstance.account?.address || "0x0000000000000000000000000000000000000000",
729
+ });
730
+ return quote || undefined;
731
+ } catch (error) {
732
+ console.warn("Error getting swap quote for bondkit token:", error);
733
+ return undefined;
734
+ }
735
+ }
736
+
737
+ /**
738
+ * Get swap quote for bondkit token → trading token
739
+ */
740
+ public async getSwapQuoteForTradingToken(
741
+ amountBondkitTokenIn: string,
742
+ slippageTolerance = 0.5,
743
+ ): Promise<SwapQuote | undefined> {
744
+ try {
745
+ // Check if swapping is available
746
+ const swapAvailable = await this.isSwapAvailable();
747
+ if (!swapAvailable) {
748
+ console.warn("DEX swapping not available - token must be in Dex phase");
749
+ return undefined;
750
+ }
751
+
752
+ const tradingTokenAddress = await this.getTradingTokenAddress();
753
+ if (!tradingTokenAddress) {
754
+ console.warn("Trading token address not available");
755
+ return undefined;
756
+ }
757
+
758
+ // Get token details for decimals
759
+ const [bondkitTokenDecimals, tradingTokenDecimals] = await Promise.all([
760
+ this.decimals(),
761
+ this.getTradingTokenDecimals(tradingTokenAddress),
762
+ ]);
763
+
764
+ if (bondkitTokenDecimals === undefined || tradingTokenDecimals === undefined) {
765
+ console.warn("Unable to fetch token decimals");
766
+ return undefined;
767
+ }
768
+
769
+ const swapService = this.getSwapService();
770
+ const quote = await swapService.getSwapQuote({
771
+ tokenIn: this.contractAddress,
772
+ tokenOut: tradingTokenAddress,
773
+ amountIn: amountBondkitTokenIn,
774
+ tokenInDecimals: bondkitTokenDecimals,
775
+ tokenOutDecimals: tradingTokenDecimals,
776
+ slippageTolerance,
777
+ recipient: this.walletClientInstance.account?.address || "0x0000000000000000000000000000000000000000",
778
+ });
779
+ return quote || undefined;
780
+ } catch (error) {
781
+ console.warn("Error getting swap quote for trading token:", error);
782
+ return undefined;
783
+ }
784
+ }
785
+
786
+ /**
787
+ * Swap trading token for bondkit token
788
+ */
789
+ public async swapTradingTokenForBondkitToken(
790
+ amountTradingTokenIn: string,
791
+ slippageTolerance = 0.5,
792
+ options?: ExecuteWriteOptions,
793
+ ): Promise<Hex | undefined> {
794
+ try {
795
+ // Check if swapping is available
796
+ const swapAvailable = await this.isSwapAvailable();
797
+ if (!swapAvailable) {
798
+ console.warn("DEX swapping not available - token must be in Dex phase");
799
+ return undefined;
800
+ }
801
+
802
+ if (!this.walletClientInstance.account && !this.walletKey) {
803
+ console.warn("Wallet key not set or client not connected for swap operation");
804
+ return undefined;
805
+ }
806
+
807
+ const tradingTokenAddress = await this.getTradingTokenAddress();
808
+ if (!tradingTokenAddress) {
809
+ console.warn("Trading token address not available");
810
+ return undefined;
811
+ }
812
+
813
+ // Get token details for decimals
814
+ const [tradingTokenDecimals, bondkitTokenDecimals] = await Promise.all([
815
+ this.getTradingTokenDecimals(tradingTokenAddress),
816
+ this.decimals(),
817
+ ]);
818
+
819
+ if (tradingTokenDecimals === undefined || bondkitTokenDecimals === undefined) {
820
+ console.warn("Unable to fetch token decimals");
821
+ return undefined;
822
+ }
823
+
824
+ const recipient =
825
+ this.walletClientInstance.account?.address ||
826
+ (this.walletKey ? privateKeyToAccount(this.walletKey).address : undefined);
827
+
828
+ if (!recipient) {
829
+ console.warn("Unable to determine recipient address");
830
+ return undefined;
831
+ }
832
+
833
+ const swapService = this.getSwapService();
834
+ const txHash = await swapService.executeSwap(
835
+ {
836
+ tokenIn: tradingTokenAddress,
837
+ tokenOut: this.contractAddress,
838
+ amountIn: amountTradingTokenIn,
839
+ tokenInDecimals: tradingTokenDecimals,
840
+ tokenOutDecimals: bondkitTokenDecimals,
841
+ slippageTolerance,
842
+ recipient,
843
+ deadline: (options?.value ? Math.floor(Date.now() / 1000) : 0) + 3600,
844
+ },
845
+ this.walletClientInstance,
846
+ );
847
+
848
+ return txHash ? (txHash as Hex) : undefined;
849
+ } catch (error) {
850
+ console.warn("Error swapping trading token for bondkit token:", error);
851
+ return undefined;
852
+ }
853
+ }
854
+
855
+ /**
856
+ * Swap bondkit token for trading token
857
+ */
858
+ public async swapBondkitTokenForTradingToken(
859
+ amountBondkitTokenIn: string,
860
+ slippageTolerance = 0.5,
861
+ options?: ExecuteWriteOptions,
862
+ ): Promise<Hex | undefined> {
863
+ try {
864
+ // Check if swapping is available
865
+ const swapAvailable = await this.isSwapAvailable();
866
+ if (!swapAvailable) {
867
+ console.warn("DEX swapping not available - token must be in Dex phase");
868
+ return undefined;
869
+ }
870
+
871
+ if (!this.walletClientInstance.account && !this.walletKey) {
872
+ console.warn("Wallet key not set or client not connected for swap operation");
873
+ return undefined;
874
+ }
875
+
876
+ const tradingTokenAddress = await this.getTradingTokenAddress();
877
+ if (!tradingTokenAddress) {
878
+ console.warn("Trading token address not available");
879
+ return undefined;
880
+ }
881
+
882
+ // Get token details for decimals
883
+ const [bondkitTokenDecimals, tradingTokenDecimals] = await Promise.all([
884
+ this.decimals(),
885
+ this.getTradingTokenDecimals(tradingTokenAddress),
886
+ ]);
887
+
888
+ if (bondkitTokenDecimals === undefined || tradingTokenDecimals === undefined) {
889
+ console.warn("Unable to fetch token decimals");
890
+ return undefined;
891
+ }
892
+
893
+ const recipient =
894
+ this.walletClientInstance.account?.address ||
895
+ (this.walletKey ? privateKeyToAccount(this.walletKey).address : undefined);
896
+
897
+ if (!recipient) {
898
+ console.warn("Unable to determine recipient address");
899
+ return undefined;
900
+ }
901
+
902
+ const swapService = this.getSwapService();
903
+ const txHash = await swapService.executeSwap(
904
+ {
905
+ tokenIn: this.contractAddress,
906
+ tokenOut: tradingTokenAddress,
907
+ amountIn: amountBondkitTokenIn,
908
+ tokenInDecimals: bondkitTokenDecimals,
909
+ tokenOutDecimals: tradingTokenDecimals,
910
+ slippageTolerance,
911
+ recipient,
912
+ deadline: (options?.value ? Math.floor(Date.now() / 1000) : 0) + 3600,
913
+ },
914
+ this.walletClientInstance,
915
+ );
916
+
917
+ return txHash ? (txHash as Hex) : undefined;
918
+ } catch (error) {
919
+ console.warn("Error swapping bondkit token for trading token:", error);
920
+ return undefined;
921
+ }
922
+ }
923
+
924
+ /**
925
+ * Helper method to get trading token decimals
926
+ */
927
+ private async getTradingTokenDecimals(tradingTokenAddress: Address): Promise<number | undefined> {
928
+ try {
929
+ // ETH has 18 decimals
930
+ if (tradingTokenAddress === "0x0000000000000000000000000000000000000000") {
931
+ return 18;
932
+ }
933
+
934
+ // For ERC20 tokens, read decimals from contract
935
+ const tradingTokenContract = getContract({
936
+ address: tradingTokenAddress,
937
+ abi: erc20Abi,
938
+ client: this.publicClient,
939
+ });
940
+
941
+ const decimals = await tradingTokenContract.read.decimals();
942
+ return Number(decimals);
943
+ } catch (error) {
944
+ console.warn("Error fetching trading token decimals:", error);
945
+ return undefined;
946
+ }
947
+ }
948
+
949
+ /**
950
+ * Get trading token symbol
951
+ * @param tradingTokenAddress Optional trading token address to avoid fetching it again
952
+ */
953
+ public async getTradingTokenSymbol(tradingTokenAddress?: Address): Promise<string | undefined> {
954
+ try {
955
+ const tokenAddress = tradingTokenAddress || (await this.getTradingTokenAddress());
956
+ if (!tokenAddress) {
957
+ return undefined;
958
+ }
959
+
960
+ // ETH symbol
961
+ if (tokenAddress === "0x0000000000000000000000000000000000000000") {
962
+ return "ETH";
963
+ }
964
+
965
+ // For ERC20 tokens, read symbol from contract
966
+ const tradingTokenContract = getContract({
967
+ address: tokenAddress,
968
+ abi: erc20Abi,
969
+ client: this.publicClient,
970
+ });
971
+
972
+ const symbol = await tradingTokenContract.read.symbol();
973
+ return symbol;
974
+ } catch (error) {
975
+ console.warn("Error fetching trading token symbol:", error);
976
+ return undefined;
977
+ }
978
+ }
979
+
660
980
  // TODO: Add other specific write methods from BondkitTokenABI.ts
661
981
  // e.g., setBondingCurve (if it exists and is external), updateArtistAddress, etc.
662
982
  }
@@ -30,14 +30,14 @@ export class BondkitTokenFactory {
30
30
  private walletClientInstance: WalletClient; // Made non-optional, initialized in constructor
31
31
  private connectedProvider?: EIP1193Provider;
32
32
 
33
- constructor(chainId: SupportedChainId, walletKey?: string) {
33
+ constructor(chainId: SupportedChainId, walletKey?: string, rpcUrl?: string) {
34
34
  if (walletKey && !walletKey.startsWith("0x")) {
35
35
  this.walletKey = `0x${walletKey}` as Hex;
36
36
  } else if (walletKey) {
37
37
  this.walletKey = walletKey as Hex;
38
38
  }
39
39
 
40
- const config = getConfig(chainId);
40
+ const config = getConfig(chainId, rpcUrl);
41
41
  this.chain = config.chain;
42
42
  this.contractAddress = config.factoryAddress;
43
43
  this.rpcUrl = config.rpcUrl;
@@ -18,9 +18,12 @@ const baseMainnetConfig: Config = {
18
18
  apiEndpoint: "https://api.b3.fun/bondkit-tokens",
19
19
  };
20
20
 
21
- export const getConfig = (chainId: number): Config => {
21
+ export const getConfig = (chainId: number, rpcUrl?: string): Config => {
22
22
  if (chainId === base.id) {
23
- return baseMainnetConfig;
23
+ return {
24
+ ...baseMainnetConfig,
25
+ rpcUrl: rpcUrl || BaseMainnetRpcUrl,
26
+ };
24
27
  }
25
28
  throw new Error(`Unsupported chainId: ${chainId}. This SDK is configured for Base (Chain ID: ${base.id}) only.`);
26
29
  };
@@ -3,3 +3,10 @@ import type { Address } from "viem";
3
3
  export const BaseBondkitTokenFactoryContractAddress: Address = "0x5d641bbB206d4B5585eCCd919F36270200A9A2Ad";
4
4
 
5
5
  export const BaseMainnetRpcUrl = "https://base-rpc.publicnode.com";
6
+
7
+ // Uniswap V4 addresses on Base
8
+ export const UniversalRouterAddress: Address = "0x6ff5693b99212da76ad316178a184ab56d299b43";
9
+ export const QuoterAddress: Address = "0x0d5e0f971ed27fbff6c2837bf31316121532048d";
10
+ export const Permit2Address: Address = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
11
+
12
+ export const B3TokenAddress: Address = "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3";
@@ -12,5 +12,8 @@ export * from "./types";
12
12
  // ABIs
13
13
  export * from "./abis";
14
14
 
15
+ // Swap functionality
16
+ export { BondkitSwapService } from "./swapService";
17
+
15
18
  // Components
16
19
  export { default as TradingView } from "./components/TradingView";