@b3dotfun/sdk 0.0.35 → 0.0.36

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 (160) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +5 -3
  2. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +2 -2
  3. package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.d.ts +3 -1
  4. package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +5 -2
  5. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +16 -0
  6. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +58 -0
  7. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +1 -0
  8. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +22 -15
  9. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +12 -4
  10. package/dist/cjs/anyspend/react/components/common/PaySection.d.ts +2 -6
  11. package/dist/cjs/anyspend/react/components/common/PaySection.js +10 -15
  12. package/dist/cjs/anyspend/react/components/index.d.ts +2 -2
  13. package/dist/cjs/anyspend/react/components/index.js +5 -5
  14. package/dist/cjs/global-account/bsmnt.d.ts +2 -0
  15. package/dist/cjs/global-account/bsmnt.js +42 -1
  16. package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
  17. package/dist/cjs/global-account/react/components/AvatarCreator/AvatarCreator.js +55 -0
  18. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
  19. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +108 -0
  20. package/dist/cjs/global-account/react/components/B3DynamicModal.js +9 -1
  21. package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
  22. package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +21 -11
  23. package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.d.ts +3 -1
  24. package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +19 -5
  25. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.d.ts +3 -1
  26. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +6 -6
  27. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3.js +2 -2
  28. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +1 -13
  29. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -3
  30. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +0 -3
  31. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +0 -3
  32. package/dist/cjs/global-account/react/components/icons/AppleIcon.d.ts +9 -0
  33. package/dist/cjs/global-account/react/components/icons/AppleIcon.js +8 -0
  34. package/dist/cjs/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
  35. package/dist/cjs/global-account/react/components/icons/DiscordIcon.js +8 -0
  36. package/dist/cjs/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
  37. package/dist/cjs/global-account/react/components/icons/FarcasterIcon.js +8 -0
  38. package/dist/cjs/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
  39. package/dist/cjs/global-account/react/components/icons/GoogleIcon.js +8 -0
  40. package/dist/cjs/global-account/react/components/icons/XIcon.d.ts +9 -0
  41. package/dist/cjs/global-account/react/components/icons/XIcon.js +8 -0
  42. package/dist/cjs/global-account/react/hooks/useAccountWallet.js +3 -2
  43. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +1 -2
  44. package/dist/cjs/global-account/react/hooks/useAuthentication.js +16 -15
  45. package/dist/cjs/global-account/react/hooks/useProfile.d.ts +1 -1
  46. package/dist/cjs/global-account/react/hooks/useRPMToken.d.ts +7 -0
  47. package/dist/cjs/global-account/react/hooks/useRPMToken.js +11 -0
  48. package/dist/cjs/global-account/react/stores/useAuthStore.d.ts +2 -4
  49. package/dist/cjs/global-account/react/stores/useAuthStore.js +2 -4
  50. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +11 -1
  51. package/dist/cjs/global-account/react/utils/updateAvatar.d.ts +4 -0
  52. package/dist/cjs/global-account/react/utils/updateAvatar.js +54 -0
  53. package/dist/esm/anyspend/react/components/AnySpend.js +5 -3
  54. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +2 -2
  55. package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.d.ts +3 -1
  56. package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +5 -2
  57. package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +16 -0
  58. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +55 -0
  59. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +1 -0
  60. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +22 -15
  61. package/dist/esm/anyspend/react/components/common/OrderDetails.js +12 -4
  62. package/dist/esm/anyspend/react/components/common/PaySection.d.ts +2 -6
  63. package/dist/esm/anyspend/react/components/common/PaySection.js +10 -15
  64. package/dist/esm/anyspend/react/components/index.d.ts +2 -2
  65. package/dist/esm/anyspend/react/components/index.js +2 -2
  66. package/dist/esm/global-account/bsmnt.d.ts +2 -0
  67. package/dist/esm/global-account/bsmnt.js +39 -0
  68. package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
  69. package/dist/esm/global-account/react/components/AvatarCreator/AvatarCreator.js +52 -0
  70. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
  71. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +102 -0
  72. package/dist/esm/global-account/react/components/B3DynamicModal.js +9 -1
  73. package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
  74. package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +22 -12
  75. package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.d.ts +3 -1
  76. package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +20 -6
  77. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.d.ts +3 -1
  78. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +6 -6
  79. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3.js +2 -2
  80. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +1 -13
  81. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -3
  82. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +0 -3
  83. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +0 -3
  84. package/dist/esm/global-account/react/components/icons/AppleIcon.d.ts +9 -0
  85. package/dist/esm/global-account/react/components/icons/AppleIcon.js +5 -0
  86. package/dist/esm/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
  87. package/dist/esm/global-account/react/components/icons/DiscordIcon.js +5 -0
  88. package/dist/esm/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
  89. package/dist/esm/global-account/react/components/icons/FarcasterIcon.js +5 -0
  90. package/dist/esm/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
  91. package/dist/esm/global-account/react/components/icons/GoogleIcon.js +5 -0
  92. package/dist/esm/global-account/react/components/icons/XIcon.d.ts +9 -0
  93. package/dist/esm/global-account/react/components/icons/XIcon.js +5 -0
  94. package/dist/esm/global-account/react/hooks/useAccountWallet.js +3 -2
  95. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +1 -2
  96. package/dist/esm/global-account/react/hooks/useAuthentication.js +16 -15
  97. package/dist/esm/global-account/react/hooks/useProfile.d.ts +1 -1
  98. package/dist/esm/global-account/react/hooks/useRPMToken.d.ts +7 -0
  99. package/dist/esm/global-account/react/hooks/useRPMToken.js +8 -0
  100. package/dist/esm/global-account/react/stores/useAuthStore.d.ts +2 -4
  101. package/dist/esm/global-account/react/stores/useAuthStore.js +2 -4
  102. package/dist/esm/global-account/react/stores/useModalStore.d.ts +11 -1
  103. package/dist/esm/global-account/react/utils/updateAvatar.d.ts +4 -0
  104. package/dist/esm/global-account/react/utils/updateAvatar.js +18 -0
  105. package/dist/styles/index.css +1 -1
  106. package/dist/types/anyspend/react/components/common/ConnectWalletPayment.d.ts +3 -1
  107. package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +16 -0
  108. package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +1 -0
  109. package/dist/types/anyspend/react/components/common/PaySection.d.ts +2 -6
  110. package/dist/types/anyspend/react/components/index.d.ts +2 -2
  111. package/dist/types/global-account/bsmnt.d.ts +2 -0
  112. package/dist/types/global-account/react/components/AvatarCreator/AvatarCreator.d.ts +6 -0
  113. package/dist/types/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +6 -0
  114. package/dist/types/global-account/react/components/LinkAccount/LinkAccount.d.ts +3 -1
  115. package/dist/types/global-account/react/components/ManageAccount/BalanceContent.d.ts +3 -1
  116. package/dist/types/global-account/react/components/ManageAccount/ManageAccount.d.ts +3 -1
  117. package/dist/types/global-account/react/components/icons/AppleIcon.d.ts +9 -0
  118. package/dist/types/global-account/react/components/icons/DiscordIcon.d.ts +9 -0
  119. package/dist/types/global-account/react/components/icons/FarcasterIcon.d.ts +9 -0
  120. package/dist/types/global-account/react/components/icons/GoogleIcon.d.ts +8 -0
  121. package/dist/types/global-account/react/components/icons/XIcon.d.ts +9 -0
  122. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +1 -2
  123. package/dist/types/global-account/react/hooks/useProfile.d.ts +1 -1
  124. package/dist/types/global-account/react/hooks/useRPMToken.d.ts +7 -0
  125. package/dist/types/global-account/react/stores/useAuthStore.d.ts +2 -4
  126. package/dist/types/global-account/react/stores/useModalStore.d.ts +11 -1
  127. package/dist/types/global-account/react/utils/updateAvatar.d.ts +4 -0
  128. package/package.json +8 -7
  129. package/src/anyspend/react/components/AnySpend.tsx +7 -6
  130. package/src/anyspend/react/components/AnyspendDepositHype.tsx +2 -5
  131. package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +6 -1
  132. package/src/anyspend/react/components/common/CryptoPaySection.tsx +153 -0
  133. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +80 -43
  134. package/src/anyspend/react/components/common/OrderDetails.tsx +13 -4
  135. package/src/anyspend/react/components/common/PaySection.tsx +64 -140
  136. package/src/anyspend/react/components/index.ts +2 -2
  137. package/src/global-account/bsmnt.ts +47 -0
  138. package/src/global-account/react/components/AvatarCreator/AvatarCreator.tsx +90 -0
  139. package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +233 -0
  140. package/src/global-account/react/components/B3DynamicModal.tsx +27 -2
  141. package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +40 -18
  142. package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +63 -35
  143. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +106 -78
  144. package/src/global-account/react/components/SignInWithB3/SignInWithB3.tsx +2 -2
  145. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +1 -13
  146. package/src/global-account/react/components/SignInWithB3/SignInWithB3Privy.tsx +1 -3
  147. package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +0 -3
  148. package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +0 -3
  149. package/src/global-account/react/components/icons/AppleIcon.tsx +33 -0
  150. package/src/global-account/react/components/icons/DiscordIcon.tsx +32 -0
  151. package/src/global-account/react/components/icons/FarcasterIcon.tsx +37 -0
  152. package/src/global-account/react/components/icons/GoogleIcon.tsx +40 -0
  153. package/src/global-account/react/components/icons/XIcon.tsx +28 -0
  154. package/src/global-account/react/hooks/useAccountWallet.tsx +3 -2
  155. package/src/global-account/react/hooks/useAuthentication.ts +18 -15
  156. package/src/global-account/react/hooks/useProfile.ts +1 -1
  157. package/src/global-account/react/hooks/useRPMToken.ts +17 -0
  158. package/src/global-account/react/stores/useAuthStore.ts +4 -8
  159. package/src/global-account/react/stores/useModalStore.ts +13 -1
  160. package/src/global-account/react/utils/updateAvatar.ts +21 -0
@@ -1,4 +1,4 @@
1
- import { Input, useProfile, useTokenData } from "@b3dotfun/sdk/global-account/react";
1
+ import { useProfile, useTokenData } from "@b3dotfun/sdk/global-account/react";
2
2
  import { formatUsername } from "@b3dotfun/sdk/shared/utils";
3
3
  import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
4
4
  import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
@@ -8,12 +8,10 @@ import { useEffect, useRef } from "react";
8
8
  import { useAccount } from "wagmi";
9
9
  import { components } from "../../../types/api";
10
10
  import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
11
- import { FiatPaymentMethod } from "./FiatPaymentMethod";
12
11
  import { OrderTokenAmount } from "./OrderTokenAmount";
13
12
  import { TokenBalance } from "./TokenBalance";
14
13
 
15
- interface PaySectionProps {
16
- paymentType: "crypto" | "fiat";
14
+ interface CryptoPaySectionProps {
17
15
  // Token state
18
16
  selectedSrcChainId: number;
19
17
  setSelectedSrcChainId: (chainId: number) => void;
@@ -24,15 +22,12 @@ interface PaySectionProps {
24
22
  setIsSrcInputDirty: (dirty: boolean) => void;
25
23
  // Payment method state
26
24
  selectedCryptoPaymentMethod: CryptoPaymentMethodType;
27
- selectedFiatPaymentMethod: FiatPaymentMethod;
28
25
  onSelectCryptoPaymentMethod: () => void;
29
- onSelectFiatPaymentMethod: () => void;
30
26
  // Quote data
31
27
  anyspendQuote?: any;
32
28
  }
33
29
 
34
- export function PaySection({
35
- paymentType,
30
+ export function CryptoPaySection({
36
31
  selectedSrcChainId,
37
32
  setSelectedSrcChainId,
38
33
  selectedSrcToken,
@@ -41,11 +36,9 @@ export function PaySection({
41
36
  setSrcAmount,
42
37
  setIsSrcInputDirty,
43
38
  selectedCryptoPaymentMethod,
44
- selectedFiatPaymentMethod,
45
39
  onSelectCryptoPaymentMethod,
46
- onSelectFiatPaymentMethod,
47
40
  anyspendQuote,
48
- }: PaySectionProps) {
41
+ }: CryptoPaySectionProps) {
49
42
  const { address: connectedAddress, isConnected } = useAccount();
50
43
  const { data: profileData } = useProfile({ address: connectedAddress });
51
44
  const connectedName = profileData?.displayName;
@@ -88,137 +81,68 @@ export function PaySection({
88
81
  >
89
82
  <div className="flex items-center justify-between">
90
83
  <div className="text-as-primary/50 flex h-7 items-center text-sm">Pay</div>
91
- {paymentType === "crypto" ? (
92
- <button
93
- className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none"
94
- onClick={onSelectCryptoPaymentMethod}
95
- >
96
- {selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (
97
- <>
98
- {isConnected ? (
99
- <div className="flex items-center gap-1">
100
- {connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "")}
101
- </div>
102
- ) : (
103
- "Connect wallet"
104
- )}
105
- <ChevronRight className="h-4 w-4" />
106
- </>
107
- ) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
108
- <>
109
- Transfer crypto
110
- <ChevronRight className="h-4 w-4" />
111
- </>
112
- ) : (
113
- <>
114
- Select payment method
115
- <ChevronRight className="h-4 w-4" />
116
- </>
117
- )}
118
- </button>
119
- ) : (
120
- <button
121
- className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors"
122
- onClick={onSelectFiatPaymentMethod}
123
- >
124
- {selectedFiatPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (
125
- <>
126
- <div className="flex items-center gap-2">
127
- <div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-600">
128
- <span className="text-xs font-bold text-white">C</span>
129
- </div>
130
- Coinbase Pay
84
+ <button
85
+ className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none"
86
+ onClick={onSelectCryptoPaymentMethod}
87
+ >
88
+ {selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (
89
+ <>
90
+ {isConnected ? (
91
+ <div className="flex items-center gap-1">
92
+ {connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "")}
131
93
  </div>
132
- <ChevronRight className="h-4 w-4" />
133
- </>
134
- ) : selectedFiatPaymentMethod === FiatPaymentMethod.STRIPE ? (
135
- <>
136
- <div className="flex items-center gap-2">
137
- <div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-600">
138
- <span className="text-xs font-bold text-white">S</span>
139
- </div>
140
- Credit/Debit Card
141
- </div>
142
- <ChevronRight className="h-4 w-4" />
143
- </>
144
- ) : (
145
- <>
146
- Select payment method
147
- <ChevronRight className="h-4 w-4" />
148
- </>
149
- )}
150
- </button>
151
- )}
94
+ ) : (
95
+ "Connect wallet"
96
+ )}
97
+ <ChevronRight className="h-4 w-4" />
98
+ </>
99
+ ) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (
100
+ <>
101
+ Global Account
102
+ <ChevronRight className="h-4 w-4" />
103
+ </>
104
+ ) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
105
+ <>
106
+ Transfer crypto
107
+ <ChevronRight className="h-4 w-4" />
108
+ </>
109
+ ) : (
110
+ <>
111
+ Select payment method
112
+ <ChevronRight className="h-4 w-4" />
113
+ </>
114
+ )}
115
+ </button>
116
+ </div>
117
+ <OrderTokenAmount
118
+ address={connectedAddress}
119
+ context="from"
120
+ inputValue={srcAmount}
121
+ onChangeInput={value => {
122
+ setIsSrcInputDirty(true);
123
+ setSrcAmount(value);
124
+ }}
125
+ chainId={selectedSrcChainId}
126
+ setChainId={setSelectedSrcChainId}
127
+ token={selectedSrcToken}
128
+ setToken={setSelectedSrcToken}
129
+ />
130
+ <div className="flex items-center justify-between">
131
+ <div className="text-as-primary/50 flex h-5 items-center text-sm">
132
+ {formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
133
+ style: "currency",
134
+ fallback: "",
135
+ })}
136
+ </div>
137
+ <TokenBalance
138
+ token={selectedSrcToken}
139
+ walletAddress={connectedAddress}
140
+ onChangeInput={value => {
141
+ setIsSrcInputDirty(true);
142
+ setSrcAmount(value);
143
+ }}
144
+ />
152
145
  </div>
153
- {paymentType === "crypto" ? (
154
- <>
155
- <OrderTokenAmount
156
- address={connectedAddress}
157
- context="from"
158
- inputValue={srcAmount}
159
- onChangeInput={value => {
160
- setIsSrcInputDirty(true);
161
- setSrcAmount(value);
162
- }}
163
- chainId={selectedSrcChainId}
164
- setChainId={setSelectedSrcChainId}
165
- token={selectedSrcToken}
166
- setToken={setSelectedSrcToken}
167
- />
168
- <div className="flex items-center justify-between">
169
- <div className="text-as-primary/50 flex h-5 items-center text-sm">
170
- {formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
171
- style: "currency",
172
- fallback: "",
173
- })}
174
- </div>
175
- <TokenBalance
176
- token={selectedSrcToken}
177
- walletAddress={connectedAddress}
178
- onChangeInput={value => {
179
- setIsSrcInputDirty(true);
180
- setSrcAmount(value);
181
- }}
182
- />
183
- </div>
184
- </>
185
- ) : (
186
- <>
187
- {/* Fiat amount input - styled like PanelOnramp */}
188
- <div className="flex items-center justify-center pb-2 pt-8">
189
- <div className="flex gap-1">
190
- <span className="text-as-tertiarry text-2xl font-bold">$</span>
191
- <Input
192
- type="text"
193
- value={srcAmount}
194
- onChange={e => setSrcAmount(e.target.value.replace(/[^0-9.]/g, ""))}
195
- placeholder="5"
196
- className="text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0"
197
- style={{
198
- width: `${Math.max(50, srcAmount.length * 34)}px`,
199
- }}
200
- />
201
- </div>
202
- </div>
203
-
204
- {/* Quick Amount Buttons */}
205
- <div className="mx-auto mb-6 inline-grid grid-cols-4 gap-2">
206
- {["5", "10", "20", "25"].map(value => (
207
- <button
208
- key={value}
209
- onClick={() => setSrcAmount(value)}
210
- className={`bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${
211
- srcAmount === value
212
- ? "border-as-border-secondary bg-as-surface-secondary"
213
- : "bg-as-surface-secondary hover:bg-as-surface-secondary"
214
- }`}
215
- >
216
- ${value}
217
- </button>
218
- ))}
219
- </div>
220
- </>
221
- )}
222
146
  </motion.div>
223
147
  );
224
148
  }
@@ -5,13 +5,14 @@ export { AnySpendBuySpin } from "./AnySpendBuySpin";
5
5
  export { AnySpendCustom } from "./AnySpendCustom";
6
6
  export * from "./AnySpendFingerprintWrapper";
7
7
  export { AnySpendNFT } from "./AnySpendNFT";
8
- export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
9
8
  export { AnySpendStakeB3 } from "./AnySpendStakeB3";
10
9
  export { AnySpendTournament } from "./AnySpendTournament";
10
+ export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
11
11
  export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
12
12
 
13
13
  // Common Components
14
14
  export { ChainTokenIcon } from "./common/ChainTokenIcon";
15
+ export { CryptoPaySection } from "./common/CryptoPaySection";
15
16
  export { CryptoReceiveSection } from "./common/CryptoReceiveSection";
16
17
  export { OrderDetails } from "./common/OrderDetails";
17
18
  export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible";
@@ -20,7 +21,6 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem";
20
21
  export { OrderStatus } from "./common/OrderStatus";
21
22
  export { OrderToken } from "./common/OrderToken";
22
23
  export { OrderTokenAmount } from "./common/OrderTokenAmount";
23
- export { PaySection } from "./common/PaySection";
24
24
  export { RecipientSelection } from "./common/RecipientSelection";
25
25
  export { StepProgress } from "./common/StepProgress";
26
26
  export { TokenBalance } from "./common/TokenBalance";
@@ -1,9 +1,12 @@
1
1
  import { createClient } from "@b3dotfun/basement-api";
2
+ import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
2
3
  import { AuthenticationClient } from "@feathersjs/authentication-client";
3
4
  import socketio from "@feathersjs/socketio-client";
4
5
  import Cookies from "js-cookie";
5
6
  import io from "socket.io-client";
6
7
 
8
+ const debug = debugB3React("bsmnt");
9
+
7
10
  // Also use b3 auth token since we are using b3-jwt strategy
8
11
  const BSMNT_AUTH_COOKIE_NAME = "b3-auth";
9
12
 
@@ -70,4 +73,48 @@ export const resetSocket = () => {
70
73
  // reset the socket connection
71
74
  };
72
75
 
76
+ export function extractAvatarIdFromUrl(url: string): string | null {
77
+ const regex = /https:\/\/models\.readyplayer\.me\/([a-f0-9]{24})\.[a-zA-Z0-9]+/;
78
+ const match = url.match(regex);
79
+ return match ? match[1] : null;
80
+ }
81
+
82
+ export const authenticateWithB3JWT = async (fullToken: string, params?: Record<string, any>) => {
83
+ // Do not authenticate if there is no token
84
+ if (!fullToken) {
85
+ console.log("No token found, not authenticating");
86
+ return null;
87
+ }
88
+
89
+ debug("Authenticating with token:12", fullToken);
90
+ try {
91
+ const response = await app.authenticate(
92
+ {
93
+ strategy: "b3-jwt",
94
+ accessToken: fullToken,
95
+ },
96
+ {
97
+ query: params || {},
98
+ },
99
+ );
100
+ debug("Authenticated", response);
101
+
102
+ // Store streamToken if it exists in the response
103
+ if (response?.streamToken) {
104
+ Cookies.set("stream-token", response.streamToken, {
105
+ expires: new Date(response.authExpires),
106
+ secure: process.env.NODE_ENV === "production",
107
+ sameSite: "strict",
108
+ });
109
+ debug("Stream token stored in cookies");
110
+ }
111
+
112
+ return response;
113
+ } catch (error) {
114
+ debug(`Authentication error:5`, error);
115
+ debug("Authentication JWT", fullToken);
116
+ return null;
117
+ }
118
+ };
119
+
73
120
  export default app;
@@ -0,0 +1,90 @@
1
+ "use client";
2
+
3
+ import { useProfile } from "@b3dotfun/sdk/global-account/react";
4
+ import { useRPMToken } from "@b3dotfun/sdk/global-account/react/hooks/useRPMToken";
5
+ import { updateAvatar } from "@b3dotfun/sdk/global-account/react/utils/updateAvatar";
6
+ import { cn } from "@b3dotfun/sdk/shared/utils/cn";
7
+ import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
8
+ import {
9
+ AvatarCreatorConfig,
10
+ AvatarCreator as AvatarCreatorRPM,
11
+ AvatarExportedEvent,
12
+ } from "@readyplayerme/react-avatar-creator";
13
+ import { useState } from "react";
14
+ import { toast } from "sonner";
15
+ import { useActiveAccount } from "thirdweb/react";
16
+
17
+ const debug = debugB3React("AvatarCreator");
18
+
19
+ const config: AvatarCreatorConfig = {
20
+ clearCache: true,
21
+ bodyType: "fullbody",
22
+ quickStart: true,
23
+ language: "en",
24
+ };
25
+
26
+ interface AvatarCreatorProps {
27
+ onSetAvatar?: () => void;
28
+ className?: string;
29
+ }
30
+
31
+ export function AvatarCreator({ onSetAvatar, className }: AvatarCreatorProps) {
32
+ const { token, refetch: refetchRPMToken } = useRPMToken();
33
+ const [loading, setIsLoading] = useState(false);
34
+ const account = useActiveAccount();
35
+ const { data: profile, refetch: refreshProfile } = useProfile({
36
+ address: account?.address,
37
+ fresh: true,
38
+ });
39
+
40
+ const hasAvatar = profile?.avatar;
41
+
42
+ const handleOnAvatarExported = async (event: AvatarExportedEvent) => {
43
+ setIsLoading(true);
44
+ debug("@@AvatarExportedEvent", event);
45
+ try {
46
+ const avatarUpload = await updateAvatar(event.data.url);
47
+ debug("@@avatarUpload", avatarUpload);
48
+
49
+ await refreshProfile();
50
+ toast.success(
51
+ hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!",
52
+ );
53
+ onSetAvatar?.();
54
+ await refetchRPMToken(undefined);
55
+ } catch (e) {
56
+ debug("@@error:AvatarCreator", e);
57
+ toast.error("Failed to update avatar. Please try again.");
58
+ }
59
+ setIsLoading(false);
60
+ };
61
+
62
+ if (loading) {
63
+ return (
64
+ <div className="flex h-[80vh] w-full flex-col items-center justify-center gap-4">
65
+ <div className="border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" />
66
+ <p className="text-muted-foreground text-sm font-medium">Saving your avatar</p>
67
+ </div>
68
+ );
69
+ }
70
+
71
+ if (!token) {
72
+ return (
73
+ <div className="flex h-[80vh] w-full flex-col items-center justify-center gap-4">
74
+ <div className="border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" />
75
+ <p className="text-muted-foreground text-sm font-medium">Loading avatar creator</p>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ return (
81
+ <div className={cn("h-[calc(90vh-2px)] w-full", className)}>
82
+ <AvatarCreatorRPM
83
+ className="h-full w-full"
84
+ subdomain="b3"
85
+ config={{ ...config, token }}
86
+ onAvatarExported={handleOnAvatarExported}
87
+ />
88
+ </div>
89
+ );
90
+ }
@@ -0,0 +1,233 @@
1
+ "use client";
2
+
3
+ import app from "@b3dotfun/sdk/global-account/app";
4
+ import { Button, useB3, useProfile } from "@b3dotfun/sdk/global-account/react";
5
+ import { cn } from "@b3dotfun/sdk/shared/utils/cn";
6
+ import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
7
+ import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
8
+ import { Check, Loader2, Upload, X } from "lucide-react";
9
+ import { useRef, useState } from "react";
10
+ import { toast } from "sonner";
11
+ import { useActiveAccount } from "thirdweb/react";
12
+ import { upload } from "thirdweb/storage";
13
+
14
+ const debug = debugB3React("AvatarEditor");
15
+
16
+ interface AvatarEditorProps {
17
+ onSetAvatar?: () => void;
18
+ className?: string;
19
+ }
20
+
21
+ export function AvatarEditor({ onSetAvatar, className }: AvatarEditorProps) {
22
+ const [selectedFile, setSelectedFile] = useState<File | null>(null);
23
+ const [previewUrl, setPreviewUrl] = useState<string | null>(null);
24
+ const [isUploading, setIsUploading] = useState(false);
25
+ const [isSaving, setIsSaving] = useState(false);
26
+ const fileInputRef = useRef<HTMLInputElement>(null);
27
+ const { setUser } = useB3();
28
+
29
+ const account = useActiveAccount();
30
+ const { data: profile, refetch: refreshProfile } = useProfile({
31
+ address: account?.address,
32
+ fresh: true,
33
+ });
34
+
35
+ // Thirdweb upload function
36
+
37
+ const hasAvatar = profile?.avatar;
38
+
39
+ const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
40
+ const file = event.target.files?.[0];
41
+ if (file) {
42
+ // Validate file type
43
+ if (!file.type.startsWith("image/")) {
44
+ toast.error("Please select an image file");
45
+ return;
46
+ }
47
+
48
+ // Validate file size (max 5MB)
49
+ if (file.size > 5 * 1024 * 1024) {
50
+ toast.error("File size must be less than 5MB");
51
+ return;
52
+ }
53
+
54
+ setSelectedFile(file);
55
+
56
+ // Create preview URL
57
+ const url = URL.createObjectURL(file);
58
+ setPreviewUrl(url);
59
+ }
60
+ };
61
+
62
+ const handleRemoveFile = () => {
63
+ setSelectedFile(null);
64
+ if (previewUrl) {
65
+ URL.revokeObjectURL(previewUrl);
66
+ setPreviewUrl(null);
67
+ }
68
+ if (fileInputRef.current) {
69
+ fileInputRef.current.value = "";
70
+ }
71
+ };
72
+
73
+ const handleUpload = async () => {
74
+ if (!selectedFile) {
75
+ toast.error("Please select an image first");
76
+ return;
77
+ }
78
+
79
+ setIsUploading(true);
80
+ try {
81
+ debug("Starting upload to IPFS", selectedFile);
82
+
83
+ // Upload to IPFS using Thirdweb
84
+ const ipfsUrl = await upload({
85
+ client,
86
+ files: [selectedFile],
87
+ });
88
+
89
+ debug("Upload successful", ipfsUrl);
90
+
91
+ // Save avatar URL using profiles service
92
+ setIsSaving(true);
93
+ const user = await app.service("users").setAvatar(
94
+ {
95
+ avatar: ipfsUrl,
96
+ },
97
+ // @ts-expect-error - our typed client is expecting context even though it's set elsewhere
98
+ {},
99
+ );
100
+ // update user
101
+ // @ts-expect-error this resolved fine, look into why expect-error needed
102
+ setUser(user);
103
+
104
+ // Refresh profile to get updated avatar
105
+ await refreshProfile();
106
+
107
+ toast.success(
108
+ hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!",
109
+ );
110
+
111
+ onSetAvatar?.();
112
+
113
+ // Clean up
114
+ handleRemoveFile();
115
+ } catch (error) {
116
+ debug("Error uploading avatar:", error);
117
+ toast.error("Failed to upload avatar. Please try again.");
118
+ } finally {
119
+ setIsUploading(false);
120
+ setIsSaving(false);
121
+ }
122
+ };
123
+
124
+ const handleFileInputClick = () => {
125
+ fileInputRef.current?.click();
126
+ };
127
+
128
+ const isLoading = isUploading || isSaving;
129
+
130
+ return (
131
+ <div className={cn("flex flex-col items-center justify-center space-y-6 p-8", className)}>
132
+ <div className="space-y-2 text-center">
133
+ <h2 className="font-neue-montreal-semibold text-b3-grey text-2xl">
134
+ {hasAvatar ? "Update Your Avatar" : "Set Your Avatar"}
135
+ </h2>
136
+ <p className="text-b3-foreground-muted font-neue-montreal-medium">
137
+ Upload an image to personalize your profile
138
+ </p>
139
+ </div>
140
+
141
+ {/* Current Avatar Display */}
142
+ {hasAvatar && !previewUrl && (
143
+ <div className="relative">
144
+ <div className="border-b3-primary-blue h-32 w-32 overflow-hidden rounded-full border-4">
145
+ <img src={profile.avatar} alt="Current avatar" className="h-full w-full object-cover" />
146
+ </div>
147
+ </div>
148
+ )}
149
+
150
+ {/* File Upload Area */}
151
+ <div className="w-full max-w-md">
152
+ {!selectedFile ? (
153
+ <div
154
+ onClick={handleFileInputClick}
155
+ className="border-b3-line hover:border-b3-primary-blue hover:bg-b3-primary-wash/20 cursor-pointer rounded-xl border-2 border-dashed p-8 text-center transition-colors"
156
+ >
157
+ <Upload className="text-b3-grey mx-auto mb-4 h-12 w-12" />
158
+ <p className="text-b3-grey font-neue-montreal-semibold mb-2">Click to select an image</p>
159
+ <p className="text-b3-foreground-muted font-neue-montreal-medium text-sm">PNG, JPG, or GIF up to 5MB</p>
160
+ </div>
161
+ ) : (
162
+ <div className="space-y-4">
163
+ {/* Preview */}
164
+ <div className="relative">
165
+ <div className="border-b3-primary-blue mx-auto h-32 w-32 overflow-hidden rounded-full border-4">
166
+ {previewUrl ? (
167
+ <img src={previewUrl} alt="Preview" className="h-full w-full object-cover" />
168
+ ) : (
169
+ <div className="bg-b3-primary-wash flex h-full w-full items-center justify-center rounded-full">
170
+ <p className="text-b3-grey font-neue-montreal-semibold text-sm">No file selected</p>
171
+ </div>
172
+ )}
173
+ </div>
174
+ <button
175
+ onClick={handleRemoveFile}
176
+ className="bg-b3-negative absolute -right-2 -top-2 flex h-8 w-8 items-center justify-center rounded-full text-white transition-colors hover:bg-red-600"
177
+ disabled={isLoading}
178
+ >
179
+ <X size={16} />
180
+ </button>
181
+ </div>
182
+
183
+ {/* File Info */}
184
+ <div className="space-y-1 text-center">
185
+ <p className="text-b3-grey font-neue-montreal-semibold text-sm">{selectedFile.name}</p>
186
+ <p className="text-b3-foreground-muted font-neue-montreal-medium text-xs">
187
+ {(selectedFile.size / 1024 / 1024).toFixed(2)} MB
188
+ </p>
189
+ </div>
190
+ </div>
191
+ )}
192
+
193
+ {/* Hidden file input */}
194
+ <input ref={fileInputRef} type="file" accept="image/*" onChange={handleFileSelect} className="hidden" />
195
+ </div>
196
+
197
+ {/* Action Buttons */}
198
+ <div className="flex w-full max-w-md gap-3">
199
+ {selectedFile && (
200
+ <Button
201
+ onClick={handleUpload}
202
+ disabled={isLoading}
203
+ className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 flex-1 text-white"
204
+ >
205
+ {isLoading ? (
206
+ <>
207
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
208
+ {isUploading ? "Uploading..." : "Saving..."}
209
+ </>
210
+ ) : (
211
+ <>
212
+ <Check className="mr-2 h-4 w-4" />
213
+ {hasAvatar ? "Update Avatar" : "Set Avatar"}
214
+ </>
215
+ )}
216
+ </Button>
217
+ )}
218
+
219
+ <Button variant="outline" onClick={handleFileInputClick} disabled={isLoading} className="flex-1">
220
+ <Upload className="mr-2 h-4 w-4" />
221
+ {selectedFile ? "Change Image" : "Select Image"}
222
+ </Button>
223
+ </div>
224
+
225
+ {/* Help Text */}
226
+ <div className="text-b3-foreground-muted font-neue-montreal-medium max-w-md text-center text-xs">
227
+ <p>
228
+ Your avatar will be uploaded to IPFS and stored securely. Make sure you have the rights to use this image.
229
+ </p>
230
+ </div>
231
+ </div>
232
+ );
233
+ }