@iota/dapp-kit 0.10.3 → 0.11.0

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 (97) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cjs/components/AccountDropdownMenu.css +50 -16
  3. package/dist/cjs/components/AccountDropdownMenu.css.css +39 -16
  4. package/dist/cjs/components/AccountDropdownMenu.css.css.map +3 -3
  5. package/dist/cjs/components/AccountDropdownMenu.css.d.ts +3 -0
  6. package/dist/cjs/components/AccountDropdownMenu.css.d.ts.map +1 -1
  7. package/dist/cjs/components/AccountDropdownMenu.css.js +12 -6
  8. package/dist/cjs/components/AccountDropdownMenu.css.js.map +2 -2
  9. package/dist/cjs/components/AccountDropdownMenu.css.map +3 -3
  10. package/dist/cjs/components/AccountDropdownMenu.d.ts.map +1 -1
  11. package/dist/cjs/components/AccountDropdownMenu.js +184 -86
  12. package/dist/cjs/components/AccountDropdownMenu.js.map +4 -4
  13. package/dist/cjs/components/ConnectButton.css +50 -16
  14. package/dist/cjs/components/ConnectButton.css.map +3 -3
  15. package/dist/cjs/components/ConnectButton.js +259 -161
  16. package/dist/cjs/components/ConnectButton.js.map +4 -4
  17. package/dist/cjs/components/IotaNameNftImage.css +11 -0
  18. package/dist/cjs/components/IotaNameNftImage.css.css +11 -0
  19. package/dist/cjs/components/IotaNameNftImage.css.css.map +7 -0
  20. package/dist/cjs/components/IotaNameNftImage.css.d.ts +2 -0
  21. package/dist/cjs/components/IotaNameNftImage.css.d.ts.map +1 -0
  22. package/dist/cjs/components/IotaNameNftImage.css.js +27 -0
  23. package/dist/cjs/components/IotaNameNftImage.css.js.map +7 -0
  24. package/dist/cjs/components/IotaNameNftImage.css.map +7 -0
  25. package/dist/cjs/components/IotaNameNftImage.d.ts +8 -0
  26. package/dist/cjs/components/IotaNameNftImage.d.ts.map +1 -0
  27. package/dist/cjs/components/IotaNameNftImage.js +165 -0
  28. package/dist/cjs/components/IotaNameNftImage.js.map +7 -0
  29. package/dist/cjs/hooks/useGetDefaultIotaName.d.ts +1 -1
  30. package/dist/cjs/hooks/useGetDefaultIotaName.d.ts.map +1 -1
  31. package/dist/cjs/hooks/useGetDefaultIotaName.js +26 -16
  32. package/dist/cjs/hooks/useGetDefaultIotaName.js.map +4 -4
  33. package/dist/cjs/hooks/useGetIotaNameAvatar.d.ts +2 -0
  34. package/dist/cjs/hooks/useGetIotaNameAvatar.d.ts.map +1 -0
  35. package/dist/cjs/hooks/useGetIotaNameAvatar.js +144 -0
  36. package/dist/cjs/hooks/useGetIotaNameAvatar.js.map +7 -0
  37. package/dist/cjs/hooks/useIotaNamesClient.d.ts +7 -0
  38. package/dist/cjs/hooks/useIotaNamesClient.d.ts.map +1 -0
  39. package/dist/cjs/hooks/useIotaNamesClient.js +71 -0
  40. package/dist/cjs/hooks/useIotaNamesClient.js.map +7 -0
  41. package/dist/cjs/index.css +50 -16
  42. package/dist/cjs/index.css.map +3 -3
  43. package/dist/cjs/index.js +171 -76
  44. package/dist/cjs/index.js.map +4 -4
  45. package/dist/esm/components/AccountDropdownMenu.css +50 -16
  46. package/dist/esm/components/AccountDropdownMenu.css.css +39 -16
  47. package/dist/esm/components/AccountDropdownMenu.css.css.map +3 -3
  48. package/dist/esm/components/AccountDropdownMenu.css.d.ts +3 -0
  49. package/dist/esm/components/AccountDropdownMenu.css.d.ts.map +1 -1
  50. package/dist/esm/components/AccountDropdownMenu.css.js +12 -6
  51. package/dist/esm/components/AccountDropdownMenu.css.js.map +2 -2
  52. package/dist/esm/components/AccountDropdownMenu.css.map +3 -3
  53. package/dist/esm/components/AccountDropdownMenu.d.ts.map +1 -1
  54. package/dist/esm/components/AccountDropdownMenu.js +177 -79
  55. package/dist/esm/components/AccountDropdownMenu.js.map +4 -4
  56. package/dist/esm/components/ConnectButton.css +50 -16
  57. package/dist/esm/components/ConnectButton.css.map +3 -3
  58. package/dist/esm/components/ConnectButton.js +236 -138
  59. package/dist/esm/components/ConnectButton.js.map +4 -4
  60. package/dist/esm/components/IotaNameNftImage.css +11 -0
  61. package/dist/esm/components/IotaNameNftImage.css.css +11 -0
  62. package/dist/esm/components/IotaNameNftImage.css.css.map +7 -0
  63. package/dist/esm/components/IotaNameNftImage.css.d.ts +2 -0
  64. package/dist/esm/components/IotaNameNftImage.css.d.ts.map +1 -0
  65. package/dist/esm/components/IotaNameNftImage.css.js +6 -0
  66. package/dist/esm/components/IotaNameNftImage.css.js.map +7 -0
  67. package/dist/esm/components/IotaNameNftImage.css.map +7 -0
  68. package/dist/esm/components/IotaNameNftImage.d.ts +8 -0
  69. package/dist/esm/components/IotaNameNftImage.d.ts.map +1 -0
  70. package/dist/esm/components/IotaNameNftImage.js +144 -0
  71. package/dist/esm/components/IotaNameNftImage.js.map +7 -0
  72. package/dist/esm/hooks/useGetDefaultIotaName.d.ts +1 -1
  73. package/dist/esm/hooks/useGetDefaultIotaName.d.ts.map +1 -1
  74. package/dist/esm/hooks/useGetDefaultIotaName.js +26 -16
  75. package/dist/esm/hooks/useGetDefaultIotaName.js.map +4 -4
  76. package/dist/esm/hooks/useGetIotaNameAvatar.d.ts +2 -0
  77. package/dist/esm/hooks/useGetIotaNameAvatar.d.ts.map +1 -0
  78. package/dist/esm/hooks/useGetIotaNameAvatar.js +123 -0
  79. package/dist/esm/hooks/useGetIotaNameAvatar.js.map +7 -0
  80. package/dist/esm/hooks/useIotaNamesClient.d.ts +7 -0
  81. package/dist/esm/hooks/useIotaNamesClient.d.ts.map +1 -0
  82. package/dist/esm/hooks/useIotaNamesClient.js +50 -0
  83. package/dist/esm/hooks/useIotaNamesClient.js.map +7 -0
  84. package/dist/esm/index.css +50 -16
  85. package/dist/esm/index.css.map +3 -3
  86. package/dist/esm/index.js +142 -47
  87. package/dist/esm/index.js.map +4 -4
  88. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  89. package/dist/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +4 -4
  91. package/src/components/AccountDropdownMenu.css.ts +24 -1
  92. package/src/components/AccountDropdownMenu.tsx +12 -2
  93. package/src/components/IotaNameNftImage.css.ts +14 -0
  94. package/src/components/IotaNameNftImage.tsx +30 -0
  95. package/src/hooks/useGetDefaultIotaName.ts +6 -22
  96. package/src/hooks/useGetIotaNameAvatar.ts +72 -0
  97. package/src/hooks/useIotaNamesClient.ts +29 -0
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "description": "A collection of React hooks and components for interacting with the IOTA blockchain and wallets.",
5
5
  "homepage": "https://docs.iota.org/developer/ts-sdk/dapp-kit/",
6
6
  "repository": "https://github.com/iotaledger/ts-packages",
7
- "version": "0.10.3",
7
+ "version": "0.11.0",
8
8
  "license": "Apache-2.0",
9
9
  "files": [
10
10
  "CHANGELOG.md",
@@ -65,9 +65,9 @@
65
65
  "@vanilla-extract/recipes": "^0.5.3",
66
66
  "clsx": "^2.1.1",
67
67
  "zustand": "^4.4.1",
68
- "@iota/iota-names-sdk": "^2.0.0",
69
- "@iota/iota-sdk": "1.15.0",
70
- "@iota/wallet-standard": "0.4.4"
68
+ "@iota/iota-sdk": "1.16.0",
69
+ "@iota/iota-names-sdk": "^2.0.1",
70
+ "@iota/wallet-standard": "0.4.6"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "@tanstack/react-query": "^5.50.1",
@@ -10,6 +10,20 @@ export const connectedAccount = style({
10
10
  gap: 8,
11
11
  });
12
12
 
13
+ export const accountName = style({
14
+ maxWidth: 140,
15
+ overflow: 'hidden',
16
+ textOverflow: 'ellipsis',
17
+ whiteSpace: 'nowrap',
18
+ });
19
+
20
+ export const accountNameMenuItem = style({
21
+ maxWidth: 120,
22
+ overflow: 'hidden',
23
+ textOverflow: 'ellipsis',
24
+ whiteSpace: 'nowrap',
25
+ });
26
+
13
27
  export const menuContainer = style({
14
28
  zIndex: 999999999,
15
29
  });
@@ -17,7 +31,7 @@ export const menuContainer = style({
17
31
  export const menuContent = style({
18
32
  display: 'flex',
19
33
  flexDirection: 'column',
20
- width: 180,
34
+ width: 220,
21
35
  maxHeight: 300,
22
36
  marginTop: 4,
23
37
  padding: 8,
@@ -51,6 +65,15 @@ export const switchAccountMenuItem = style({
51
65
  display: 'flex',
52
66
  justifyContent: 'space-between',
53
67
  alignItems: 'center',
68
+ gap: 8,
69
+ });
70
+
71
+ export const accountIdentity = style({
72
+ display: 'flex',
73
+ alignItems: 'center',
74
+ gap: 8,
75
+ minWidth: 0,
76
+ overflow: 'hidden',
54
77
  });
55
78
 
56
79
  export const separator = style({
@@ -13,6 +13,7 @@ import { useSwitchAccount } from '../hooks/wallet/useSwitchAccount.js';
13
13
  import * as styles from './AccountDropdownMenu.css.js';
14
14
  import { CheckIcon } from './icons/CheckIcon.js';
15
15
  import { ChevronIcon } from './icons/ChevronIcon.js';
16
+ import { IotaNameNftImage } from './IotaNameNftImage.js';
16
17
  import { StyleMarker } from './styling/StyleMarker.js';
17
18
  import { Button } from './ui/Button.js';
18
19
  import { Text } from './ui/Text.js';
@@ -40,7 +41,11 @@ export function AccountDropdownMenu({
40
41
  <StyleMarker>
41
42
  <DropdownMenu.Trigger asChild>
42
43
  <Button size={size} className={styles.connectedAccount}>
43
- <Text mono weight="bold">
44
+ <IotaNameNftImage
45
+ address={currentAccount.address}
46
+ iotaNamesEnabled={iotaNamesEnabled}
47
+ />
48
+ <Text mono weight="bold" className={styles.accountName}>
44
49
  {displayAccount}
45
50
  </Text>
46
51
  <ChevronIcon />
@@ -92,7 +97,12 @@ export function AccountDropdownMenuItem({
92
97
  className={clsx(styles.menuItem, styles.switchAccountMenuItem)}
93
98
  onSelect={() => switchAccount({ account })}
94
99
  >
95
- <Text mono>{displayAccount}</Text>
100
+ <div className={styles.accountIdentity}>
101
+ <IotaNameNftImage address={account.address} iotaNamesEnabled={iotaNamesEnabled} />
102
+ <Text mono className={styles.accountNameMenuItem}>
103
+ {displayAccount}
104
+ </Text>
105
+ </div>
96
106
  {active ? <CheckIcon /> : null}
97
107
  </DropdownMenu.Item>
98
108
  );
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2026 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { style } from '@vanilla-extract/css';
5
+
6
+ import { themeVars } from '../themes/themeContract.js';
7
+
8
+ export const image = style({
9
+ width: 24,
10
+ height: 24,
11
+ flexShrink: 0,
12
+ borderRadius: themeVars.radii.full,
13
+ objectFit: 'cover',
14
+ });
@@ -0,0 +1,30 @@
1
+ // Copyright (c) 2026 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { useState } from 'react';
5
+
6
+ import { useGetIotaNameAvatar } from '../hooks/useGetIotaNameAvatar.js';
7
+ import * as styles from './IotaNameNftImage.css.js';
8
+
9
+ interface IotaNameNftImageProps {
10
+ address: string | null | undefined;
11
+ iotaNamesEnabled: boolean;
12
+ alt?: string;
13
+ }
14
+
15
+ export function IotaNameNftImage({
16
+ address,
17
+ iotaNamesEnabled,
18
+ alt = 'name NFT avatar',
19
+ }: IotaNameNftImageProps) {
20
+ const { data: imageUrl, isLoading } = useGetIotaNameAvatar(address, iotaNamesEnabled);
21
+ const [imgError, setImgError] = useState(false);
22
+
23
+ if (!iotaNamesEnabled || isLoading || !imageUrl || imgError) {
24
+ return null;
25
+ }
26
+
27
+ return (
28
+ <img src={imageUrl} alt={alt} className={styles.image} onError={() => setImgError(true)} />
29
+ );
30
+ }
@@ -1,35 +1,19 @@
1
1
  // Copyright (c) 2025 IOTA Stiftung
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { getNetwork } from '@iota/iota-sdk/client';
4
+ import { normalizeIotaName } from '@iota/iota-names-sdk';
5
5
  import { useQuery } from '@tanstack/react-query';
6
- import { IotaNamesClient, normalizeIotaName } from '@iota/iota-names-sdk';
7
- import { useIotaClientContext } from './useIotaClient.js';
8
- import { useMemo } from 'react';
9
- import { IotaGraphQLClient } from '@iota/iota-sdk/graphql';
6
+
7
+ import { useIotaNamesClient } from './useIotaNamesClient.js';
10
8
 
11
9
  export function useGetDefaultIotaName(
12
10
  address: string | null | undefined,
13
11
  iotaNamesEnabled: boolean,
14
12
  ) {
15
- const iotaContext = useIotaClientContext();
16
- const network = getNetwork(iotaContext.network);
17
-
18
- const iotaNamesClient = useMemo(() => {
19
- const iotaGraphQLClient = new IotaGraphQLClient({
20
- url: network.graphql!,
21
- });
22
-
23
- return new IotaNamesClient({
24
- graphQlClient: iotaGraphQLClient,
25
- network: network.id,
26
- });
27
- }, [network.id]);
28
-
29
- const iotaNamesSupported = !!iotaNamesClient.config;
13
+ const { iotaNamesClient, networkId, isSupported } = useIotaNamesClient();
30
14
 
31
15
  return useQuery({
32
- queryKey: ['iota-name', 'default-name', address],
16
+ queryKey: ['iota-name', 'default-name', address, networkId],
33
17
  queryFn: async () => {
34
18
  if (!address) return null;
35
19
 
@@ -37,7 +21,7 @@ export function useGetDefaultIotaName(
37
21
 
38
22
  return name ? normalizeIotaName(name) : name;
39
23
  },
40
- enabled: !!iotaNamesClient && !!address && iotaNamesEnabled && iotaNamesSupported,
24
+ enabled: !!address && iotaNamesEnabled && isSupported,
41
25
  staleTime: 1000 * 60 * 10,
42
26
  });
43
27
  }
@@ -0,0 +1,72 @@
1
+ // Copyright (c) 2026 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { getSubnameRegistrationType, isSubname, normalizeIotaName } from '@iota/iota-names-sdk';
5
+ import { useQuery } from '@tanstack/react-query';
6
+
7
+ import { useGetDefaultIotaName } from './useGetDefaultIotaName.js';
8
+ import { useIotaClient } from './useIotaClient.js';
9
+ import { useIotaNamesClient } from './useIotaNamesClient.js';
10
+
11
+ export function useGetIotaNameAvatar(
12
+ address: string | null | undefined,
13
+ iotaNamesEnabled: boolean,
14
+ ) {
15
+ const client = useIotaClient();
16
+ const { iotaNamesClient, networkId, isSupported } = useIotaNamesClient();
17
+ const { data: name } = useGetDefaultIotaName(address, iotaNamesEnabled);
18
+
19
+ return useQuery({
20
+ // eslint-disable-next-line @tanstack/query/exhaustive-deps
21
+ queryKey: ['iota-name', 'avatar', name, networkId],
22
+ queryFn: async () => {
23
+ if (!name || !address || !iotaNamesClient) return null;
24
+
25
+ const nameRecord = await iotaNamesClient.getNameRecord(name);
26
+ if (!nameRecord) return null;
27
+
28
+ const avatarObjectId =
29
+ nameRecord.avatar ??
30
+ (isSubname(name) ? await findSubnameNftId() : nameRecord.nftId);
31
+ if (!avatarObjectId) return null;
32
+
33
+ const objectResponse = await client.getObject({
34
+ id: avatarObjectId,
35
+ options: { showDisplay: true },
36
+ });
37
+
38
+ return objectResponse?.data?.display?.data?.image_url ?? null;
39
+
40
+ async function findSubnameNftId() {
41
+ let subnameType: string;
42
+ try {
43
+ subnameType = getSubnameRegistrationType(
44
+ iotaNamesClient!.getPackage('packageId', 'v1'),
45
+ );
46
+ } catch {
47
+ return null;
48
+ }
49
+
50
+ const { data } = await client.getOwnedObjects({
51
+ owner: address!,
52
+ filter: { StructType: subnameType },
53
+ options: { showDisplay: true },
54
+ });
55
+
56
+ return (
57
+ data.find((object) => {
58
+ try {
59
+ return (
60
+ normalizeIotaName(object.data?.display?.data?.name ?? '') === name
61
+ );
62
+ } catch {
63
+ return false;
64
+ }
65
+ })?.data?.objectId ?? null
66
+ );
67
+ }
68
+ },
69
+ enabled: iotaNamesEnabled && isSupported && !!name && !!address,
70
+ staleTime: 1000 * 60 * 5,
71
+ });
72
+ }
@@ -0,0 +1,29 @@
1
+ // Copyright (c) 2026 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { IotaGraphQLClient } from '@iota/iota-sdk/graphql';
5
+ import { IotaNamesClient } from '@iota/iota-names-sdk';
6
+ import { getNetwork } from '@iota/iota-sdk/client';
7
+ import { useMemo } from 'react';
8
+
9
+ import { useIotaClientContext } from './useIotaClient.js';
10
+
11
+ export function useIotaNamesClient() {
12
+ const { network: networkId } = useIotaClientContext();
13
+ const network = getNetwork(networkId);
14
+
15
+ const iotaNamesClient = useMemo(() => {
16
+ if (!network.graphql) return null;
17
+
18
+ return new IotaNamesClient({
19
+ graphQlClient: new IotaGraphQLClient({ url: network.graphql }),
20
+ network: network.id,
21
+ });
22
+ }, [network.id, network.graphql]);
23
+
24
+ return {
25
+ iotaNamesClient,
26
+ networkId: network.id,
27
+ isSupported: !!iotaNamesClient?.config,
28
+ };
29
+ }