@b3dotfun/sdk 0.0.31-alpha.0 → 0.0.31-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.
Files changed (31) hide show
  1. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +2 -2
  2. package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +1 -0
  3. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +7 -3
  4. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +4 -1
  5. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +47 -17
  6. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
  7. package/dist/cjs/global-account/react/components/B3Provider/types.d.ts +4 -5
  8. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +53 -1
  9. package/dist/cjs/global-account/react/hooks/useSiwe.js +5 -5
  10. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +2 -2
  11. package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +1 -0
  12. package/dist/esm/anyspend/react/components/common/OrderDetails.js +7 -3
  13. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +4 -1
  14. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +49 -19
  15. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
  16. package/dist/esm/global-account/react/components/B3Provider/types.d.ts +4 -5
  17. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +54 -5
  18. package/dist/esm/global-account/react/hooks/useSiwe.js +5 -5
  19. package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +1 -0
  20. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +4 -1
  21. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
  22. package/dist/types/global-account/react/components/B3Provider/types.d.ts +4 -5
  23. package/package.json +2 -2
  24. package/src/anyspend/react/components/AnyspendDepositHype.tsx +2 -1
  25. package/src/anyspend/react/components/common/OrderDetails.tsx +6 -2
  26. package/src/anyspend/react/hooks/useAnyspendFlow.ts +53 -16
  27. package/src/global-account/react/components/B3Provider/B3Provider.native.tsx +2 -2
  28. package/src/global-account/react/components/B3Provider/B3Provider.tsx +2 -2
  29. package/src/global-account/react/components/B3Provider/types.ts +4 -5
  30. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +147 -3
  31. package/src/global-account/react/hooks/useSiwe.tsx +5 -5
@@ -1,3 +1,4 @@
1
+ import app from "@b3dotfun/sdk/global-account/app";
1
2
  import {
2
3
  Button,
3
4
  ManageAccountModalProps,
@@ -8,16 +9,18 @@ import {
8
9
  TWSignerWithMetadata,
9
10
  useAccountAssets,
10
11
  useAuthentication,
12
+ useB3,
11
13
  useGetAllTWSigners,
12
14
  useModalStore,
15
+ useQueryB3,
13
16
  useRemoveSessionKey,
14
17
  } from "@b3dotfun/sdk/global-account/react";
15
18
  import { SignOutIcon } from "@b3dotfun/sdk/global-account/react/components/icons/SignOutIcon";
16
19
  import { formatNumber } from "@b3dotfun/sdk/shared/utils/formatNumber";
17
-
18
20
  import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
19
- import { BarChart3, Coins, Image, LinkIcon, Loader2, Settings, UnlinkIcon } from "lucide-react";
20
- import { useState } from "react";
21
+ import { BarChart3, Coins, Copy, Image, LinkIcon, Loader2, Pencil, Settings, UnlinkIcon } from "lucide-react";
22
+ import { useRef, useState } from "react";
23
+ import { toast } from "sonner";
21
24
  import { Chain } from "thirdweb";
22
25
  import { useActiveAccount, useProfiles, useUnlinkProfile } from "thirdweb/react";
23
26
  import { formatUnits } from "viem";
@@ -26,6 +29,7 @@ import { getProfileDisplayInfo } from "../../utils/profileDisplay";
26
29
  import { AccountAssets } from "../AccountAssets/AccountAssets";
27
30
  import { ContentTokens } from "./ContentTokens";
28
31
 
32
+ import { Referrals, Users } from "@b3dotfun/b3-api";
29
33
  import { BalanceContent } from "./BalanceContent";
30
34
 
31
35
  type TabValue = "overview" | "tokens" | "nfts" | "apps" | "settings";
@@ -130,6 +134,50 @@ export function ManageAccount({
130
134
  const { data: profilesRaw = [], isLoading: isLoadingProfiles } = useProfiles({ client });
131
135
  const { mutate: unlinkProfile, isPending: isUnlinking } = useUnlinkProfile();
132
136
  const { setB3ModalOpen, setB3ModalContentType, isLinking } = useModalStore();
137
+ const { user, setUser } = useB3();
138
+ const [isUpdatingCode, setIsUpdatingCode] = useState(false);
139
+ const [newReferralCode, setNewReferralCode] = useState("");
140
+ const [isEditingCode, setIsEditingCode] = useState(false);
141
+ const referallCodeRef = useRef<HTMLInputElement>(null);
142
+ const { data: referrals, isLoading: isLoadingReferrals } = useQueryB3(
143
+ "referrals",
144
+ "find",
145
+ { query: { referrerId: user?.userId } },
146
+ !!user?.userId,
147
+ );
148
+
149
+ // Fetch referred users
150
+ const currentReferralCode = user?.referralCode || user?.userId || "";
151
+
152
+ const handleCopyCode = async () => {
153
+ try {
154
+ await navigator.clipboard.writeText(currentReferralCode);
155
+ toast.success("Referral code copied to clipboard!");
156
+ } catch (error) {
157
+ toast.error("Failed to copy referral code");
158
+ }
159
+ };
160
+
161
+ const handleUpdateReferralCode = async () => {
162
+ if (!newReferralCode) return;
163
+
164
+ setIsUpdatingCode(true);
165
+ try {
166
+ // @ts-expect-error - setReferralCode is not typed for some reason
167
+ const newUser = await app.service("users").setReferralCode({
168
+ userId: user?.userId,
169
+ referralCode: newReferralCode,
170
+ });
171
+ setUser(newUser as unknown as Users);
172
+ toast.success("Referral code updated successfully!");
173
+ setIsEditingCode(false);
174
+ setNewReferralCode("");
175
+ } catch (error) {
176
+ toast.error("Failed to update referral code");
177
+ } finally {
178
+ setIsUpdatingCode(false);
179
+ }
180
+ };
133
181
 
134
182
  const profiles = profilesRaw
135
183
  .filter((profile: any) => !["custom_auth_endpoint", "siwe"].includes(profile.type))
@@ -241,6 +289,102 @@ export function ManageAccount({
241
289
  )}
242
290
  </div>
243
291
 
292
+ {/* Referral Section */}
293
+ <div className="space-y-4">
294
+ <h3 className="text-b3-grey font-neue-montreal-semibold text-xl">Referrals</h3>
295
+
296
+ {/* Referral Code */}
297
+ <div className="bg-b3-line rounded-xl p-4">
298
+ {isEditingCode && (
299
+ <div>
300
+ <div className="text-b3-grey font-neue-montreal-semibold">Your Referral Code</div>
301
+ <div className="text-b3-foreground-muted font-neue-montreal-medium text-sm">
302
+ Share this code with friends to earn rewards
303
+ </div>
304
+ </div>
305
+ )}
306
+ <div className="flex items-center justify-between">
307
+ {!isEditingCode && (
308
+ <div>
309
+ <div className="text-b3-grey font-neue-montreal-semibold">Your Referral Code</div>
310
+ <div className="text-b3-foreground-muted font-neue-montreal-medium text-sm">
311
+ Share this code with friends to earn rewards
312
+ </div>
313
+ </div>
314
+ )}
315
+ <div className="flex items-center gap-2">
316
+ {isEditingCode ? (
317
+ <div className="flex items-center gap-2">
318
+ <input
319
+ type="text"
320
+ value={newReferralCode}
321
+ onChange={e => setNewReferralCode(e.target.value)}
322
+ className="rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm"
323
+ placeholder="Enter new code"
324
+ ref={referallCodeRef}
325
+ />
326
+ <Button size="sm" onClick={handleUpdateReferralCode} disabled={isUpdatingCode || !newReferralCode}>
327
+ {isUpdatingCode ? <Loader2 className="h-4 w-4 animate-spin" /> : "Save"}
328
+ </Button>
329
+ <Button
330
+ size="sm"
331
+ variant="ghost"
332
+ onClick={() => {
333
+ setIsEditingCode(false);
334
+ setNewReferralCode("");
335
+ }}
336
+ >
337
+ Cancel
338
+ </Button>
339
+ </div>
340
+ ) : (
341
+ <>
342
+ <div className="rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm">
343
+ {currentReferralCode}
344
+ </div>
345
+ <Button size="icon" variant="ghost" onClick={handleCopyCode}>
346
+ <Copy className="h-4 w-4" />
347
+ </Button>
348
+ <Button
349
+ size="icon"
350
+ variant="ghost"
351
+ onClick={() => {
352
+ setIsEditingCode(true);
353
+ setTimeout(() => {
354
+ referallCodeRef.current?.focus();
355
+ }, 100);
356
+ }}
357
+ >
358
+ <Pencil className="h-4 w-4" />
359
+ </Button>
360
+ </>
361
+ )}
362
+ </div>
363
+ </div>
364
+ </div>
365
+
366
+ {/* Referred Users */}
367
+ <div className="bg-b3-line rounded-xl p-4">
368
+ <div className="text-b3-grey font-neue-montreal-semibold mb-4">Referred Users</div>
369
+ {isLoadingReferrals ? (
370
+ <div className="flex justify-center py-4">
371
+ <Loader2 className="h-6 w-6 animate-spin text-gray-400" />
372
+ </div>
373
+ ) : referrals?.data?.length ? (
374
+ <div className="space-y-3">
375
+ {referrals.data.map((referral: Referrals) => (
376
+ <div key={String(referral._id)} className="flex items-center justify-between rounded-lg bg-white p-3">
377
+ <div className="text-sm font-medium">{referral.referreeId}</div>
378
+ <div className="text-sm text-gray-500">{new Date(referral.createdAt).toLocaleDateString()}</div>
379
+ </div>
380
+ ))}
381
+ </div>
382
+ ) : (
383
+ <div className="py-4 text-center text-gray-500">No referred users yet</div>
384
+ )}
385
+ </div>
386
+ </div>
387
+
244
388
  {/* Additional Settings Sections */}
245
389
  <div className="space-y-4">
246
390
  <h3 className="text-b3-grey font-neue-montreal-semibold text-xl">Account Preferences</h3>
@@ -5,13 +5,13 @@ import { Account } from "thirdweb/wallets";
5
5
  import { useSearchParam } from "./useSearchParamsSSR";
6
6
 
7
7
  export function useSiwe() {
8
- const referrerId = useSearchParam("referrerId");
8
+ const referralCode = useSearchParam("referralCode");
9
9
 
10
10
  const authenticate = useCallback(
11
11
  async (account: Account, partnerId: string) => {
12
12
  if (!account || !account.signMessage) throw new Error("Account not found");
13
13
 
14
- console.log("@@useAuthenticate:referrerId", referrerId);
14
+ console.log("@@useAuthenticate:referralCode", referralCode);
15
15
  // generate challenge
16
16
  const challenge = await app.service("global-accounts-challenge").create({
17
17
  address: account.address,
@@ -32,15 +32,15 @@ export function useSiwe() {
32
32
  signature,
33
33
  serverSignature: challenge.serverSignature,
34
34
  nonce: challenge.nonce,
35
- // http://localhost:5173/?referrerId=cd8fda06-3840-43d3-8f35-ae9472a13759
36
- referrerId: referrerId,
35
+ // http://localhost:5173/?referralCode=GIO2
36
+ referralCode,
37
37
  partnerId: partnerId,
38
38
  });
39
39
  debug("@@useAuthenticate:response", response);
40
40
 
41
41
  return response;
42
42
  },
43
- [referrerId],
43
+ [referralCode],
44
44
  );
45
45
 
46
46
  return {