thirdweb 5.80.0 → 5.80.1-nightly-ce3e850fdbf34911e20919ecc2674e4a63f08fa3-20241226000321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/adapters/ethers6.js +1 -1
- package/dist/cjs/contract/deployment/utils/bootstrap.js +29 -11
- package/dist/cjs/contract/deployment/utils/bootstrap.js.map +1 -1
- package/dist/cjs/contract/deployment/zksync/implementations.js +27 -0
- package/dist/cjs/contract/deployment/zksync/implementations.js.map +1 -0
- package/dist/cjs/extensions/prebuilts/get-required-transactions.js +5 -2
- package/dist/cjs/extensions/prebuilts/get-required-transactions.js.map +1 -1
- package/dist/cjs/react/core/utils/walletIcon.js +3 -0
- package/dist/cjs/react/core/utils/walletIcon.js.map +1 -1
- package/dist/cjs/react/web/ui/MediaRenderer/MediaRenderer.js +18 -8
- package/dist/cjs/react/web/ui/MediaRenderer/MediaRenderer.js.map +1 -1
- package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js +25 -0
- package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/NFT/media.js +24 -12
- package/dist/cjs/react/web/ui/prebuilt/NFT/media.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/NFT/name.js +24 -12
- package/dist/cjs/react/web/ui/prebuilt/NFT/name.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/wallets/manager/index.js +2 -2
- package/dist/cjs/wallets/manager/index.js.map +1 -1
- package/dist/esm/adapters/ethers6.js +1 -1
- package/dist/esm/contract/deployment/utils/bootstrap.js +29 -11
- package/dist/esm/contract/deployment/utils/bootstrap.js.map +1 -1
- package/dist/esm/contract/deployment/zksync/implementations.js +24 -0
- package/dist/esm/contract/deployment/zksync/implementations.js.map +1 -0
- package/dist/esm/extensions/prebuilts/get-required-transactions.js +5 -2
- package/dist/esm/extensions/prebuilts/get-required-transactions.js.map +1 -1
- package/dist/esm/react/core/utils/walletIcon.js +3 -0
- package/dist/esm/react/core/utils/walletIcon.js.map +1 -1
- package/dist/esm/react/web/ui/MediaRenderer/MediaRenderer.js +12 -3
- package/dist/esm/react/web/ui/MediaRenderer/MediaRenderer.js.map +1 -1
- package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js +24 -0
- package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/NFT/media.js +23 -12
- package/dist/esm/react/web/ui/prebuilt/NFT/media.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/NFT/name.js +23 -12
- package/dist/esm/react/web/ui/prebuilt/NFT/name.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/wallets/manager/index.js +2 -2
- package/dist/esm/wallets/manager/index.js.map +1 -1
- package/dist/types/adapters/ethers6.d.ts +1 -1
- package/dist/types/contract/deployment/utils/bootstrap.d.ts.map +1 -1
- package/dist/types/contract/deployment/zksync/implementations.d.ts +3 -0
- package/dist/types/contract/deployment/zksync/implementations.d.ts.map +1 -0
- package/dist/types/extensions/prebuilts/get-required-transactions.d.ts +1 -1
- package/dist/types/extensions/prebuilts/get-required-transactions.d.ts.map +1 -1
- package/dist/types/react/core/utils/walletIcon.d.ts +3 -0
- package/dist/types/react/core/utils/walletIcon.d.ts.map +1 -1
- package/dist/types/react/web/ui/MediaRenderer/MediaRenderer.d.ts +12 -0
- package/dist/types/react/web/ui/MediaRenderer/MediaRenderer.d.ts.map +1 -1
- package/dist/types/react/web/ui/MediaRenderer/useResolvedMediaType.d.ts +8 -0
- package/dist/types/react/web/ui/MediaRenderer/useResolvedMediaType.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/NFT/media.d.ts +10 -0
- package/dist/types/react/web/ui/prebuilt/NFT/media.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/NFT/name.d.ts +10 -0
- package/dist/types/react/web/ui/prebuilt/NFT/name.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/adapters/ethers6.ts +1 -1
- package/src/contract/deployment/utils/bootstrap.test.ts +44 -1
- package/src/contract/deployment/utils/bootstrap.ts +38 -11
- package/src/contract/deployment/zksync/implementations.ts +24 -0
- package/src/extensions/prebuilts/get-required-transactions.test.ts +14 -1
- package/src/extensions/prebuilts/get-required-transactions.ts +6 -2
- package/src/react/core/hooks/wallets/useSwitchActiveWalletChain.test.tsx +51 -0
- package/src/react/core/providers/connection-manager.test.tsx +11 -0
- package/src/react/core/utils/isSmartWallet.test.ts +19 -0
- package/src/react/core/utils/storage.test.ts +57 -0
- package/src/react/core/utils/structuralSharing.test.ts +55 -0
- package/src/react/core/utils/walletIcon.test.ts +81 -0
- package/src/react/core/utils/walletIcon.ts +3 -0
- package/src/react/web/ui/MediaRenderer/MediaRenderer.test.tsx +193 -2
- package/src/react/web/ui/MediaRenderer/MediaRenderer.tsx +12 -3
- package/src/react/web/ui/MediaRenderer/icons.test.tsx +80 -0
- package/src/react/web/ui/MediaRenderer/mime/mime.test.ts +66 -0
- package/src/react/web/ui/MediaRenderer/useResolvedMediaType.test.tsx +27 -0
- package/src/react/web/ui/MediaRenderer/useResolvedMediaType.ts +28 -0
- package/src/react/web/ui/hooks/useCopyClipboard.test.tsx +41 -0
- package/src/react/web/ui/hooks/useDebouncedValue.test.tsx +107 -0
- package/src/react/web/ui/hooks/useShowMore.test.tsx +83 -0
- package/src/react/web/ui/prebuilt/Chain/name.test.tsx +36 -28
- package/src/react/web/ui/prebuilt/NFT/media.test.tsx +58 -1
- package/src/react/web/ui/prebuilt/NFT/media.tsx +32 -13
- package/src/react/web/ui/prebuilt/NFT/name.test.tsx +37 -1
- package/src/react/web/ui/prebuilt/NFT/name.tsx +29 -13
- package/src/react/web/utils/resolveMimeType.test.ts +63 -0
- package/src/version.ts +1 -1
- package/src/wallets/manager/index.ts +2 -2
- package/src/wallets/smart/smart.test.ts +1 -1
@@ -0,0 +1,83 @@
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
2
|
+
import { act, renderHook } from "~test/react-render.js";
|
3
|
+
import { useShowMore } from "./useShowMore.js";
|
4
|
+
|
5
|
+
describe("useShowMore", () => {
|
6
|
+
it("should initialize with the correct number of items to show", () => {
|
7
|
+
const { result } = renderHook(() => useShowMore(5, 3));
|
8
|
+
expect(result.current.itemsToShow).toBe(5);
|
9
|
+
});
|
10
|
+
|
11
|
+
it("should increase itemsToShow when the last item comes into view", () => {
|
12
|
+
const { result } = renderHook(() => useShowMore(5, 3));
|
13
|
+
|
14
|
+
// Simulate the last item coming into view
|
15
|
+
const lastItem = document.createElement("div");
|
16
|
+
const observerCallback = vi.fn();
|
17
|
+
|
18
|
+
const observer = new IntersectionObserver(observerCallback);
|
19
|
+
vi.spyOn(window, "IntersectionObserver").mockImplementation((callback) => {
|
20
|
+
observerCallback.mockImplementation(callback);
|
21
|
+
return observer;
|
22
|
+
});
|
23
|
+
|
24
|
+
act(() => {
|
25
|
+
result.current.lastItemRef(lastItem);
|
26
|
+
observerCallback([{ isIntersecting: true }]); // Simulate intersection
|
27
|
+
});
|
28
|
+
|
29
|
+
expect(result.current.itemsToShow).toBe(8); // 5 + 3
|
30
|
+
});
|
31
|
+
|
32
|
+
it("should not increase itemsToShow if the last item is not in view", () => {
|
33
|
+
const { result } = renderHook(() => useShowMore(5, 3));
|
34
|
+
|
35
|
+
// Simulate the last item not coming into view
|
36
|
+
const lastItem = document.createElement("div");
|
37
|
+
|
38
|
+
const observerCallback = vi.fn();
|
39
|
+
|
40
|
+
const observer = new IntersectionObserver(observerCallback);
|
41
|
+
vi.spyOn(window, "IntersectionObserver").mockImplementation((callback) => {
|
42
|
+
observerCallback.mockImplementation(callback);
|
43
|
+
return observer;
|
44
|
+
});
|
45
|
+
|
46
|
+
act(() => {
|
47
|
+
result.current.lastItemRef(lastItem);
|
48
|
+
observerCallback([{ isIntersecting: false }]); // Simulate no intersection
|
49
|
+
});
|
50
|
+
|
51
|
+
expect(result.current.itemsToShow).toBe(5); // Should remain unchanged
|
52
|
+
});
|
53
|
+
|
54
|
+
it("should handle multiple intersections correctly", () => {
|
55
|
+
const { result } = renderHook(() => useShowMore(5, 3));
|
56
|
+
|
57
|
+
// Simulate the last item coming into view multiple times
|
58
|
+
const lastItem = document.createElement("div");
|
59
|
+
|
60
|
+
const observerCallback = vi.fn();
|
61
|
+
|
62
|
+
const observer = new IntersectionObserver(observerCallback);
|
63
|
+
vi.spyOn(window, "IntersectionObserver").mockImplementation((callback) => {
|
64
|
+
observerCallback.mockImplementation(callback);
|
65
|
+
return observer;
|
66
|
+
});
|
67
|
+
|
68
|
+
act(() => {
|
69
|
+
result.current.lastItemRef(lastItem);
|
70
|
+
|
71
|
+
// First intersection
|
72
|
+
observerCallback([{ isIntersecting: true }]);
|
73
|
+
|
74
|
+
// Second intersection
|
75
|
+
observerCallback([{ isIntersecting: true }]);
|
76
|
+
|
77
|
+
// Third intersection
|
78
|
+
observerCallback([{ isIntersecting: true }]);
|
79
|
+
});
|
80
|
+
|
81
|
+
expect(result.current.itemsToShow).toBe(14); // 5 + (3 * 3)
|
82
|
+
});
|
83
|
+
});
|
@@ -13,13 +13,15 @@ describe.runIf(process.env.TW_SECRET_KEY)("ChainName component", () => {
|
|
13
13
|
<ChainName />
|
14
14
|
</ChainProvider>,
|
15
15
|
);
|
16
|
-
await waitFor(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
await waitFor(
|
17
|
+
() =>
|
18
|
+
expect(
|
19
|
+
screen.getByText("Ethereum", {
|
20
|
+
exact: true,
|
21
|
+
selector: "span",
|
22
|
+
}),
|
23
|
+
).toBeInTheDocument(),
|
24
|
+
{ timeout: 2000 },
|
23
25
|
);
|
24
26
|
});
|
25
27
|
|
@@ -29,13 +31,15 @@ describe.runIf(process.env.TW_SECRET_KEY)("ChainName component", () => {
|
|
29
31
|
<ChainName />
|
30
32
|
</ChainProvider>,
|
31
33
|
);
|
32
|
-
await waitFor(
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
await waitFor(
|
35
|
+
() =>
|
36
|
+
expect(
|
37
|
+
screen.getByText("Ethereum Mainnet", {
|
38
|
+
exact: true,
|
39
|
+
selector: "span",
|
40
|
+
}),
|
41
|
+
).toBeInTheDocument(),
|
42
|
+
{ timeout: 2000 },
|
39
43
|
);
|
40
44
|
});
|
41
45
|
|
@@ -45,13 +49,15 @@ describe.runIf(process.env.TW_SECRET_KEY)("ChainName component", () => {
|
|
45
49
|
<ChainName formatFn={(str: string) => `${str}-formatted`} />
|
46
50
|
</ChainProvider>,
|
47
51
|
);
|
48
|
-
await waitFor(
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
await waitFor(
|
53
|
+
() =>
|
54
|
+
expect(
|
55
|
+
screen.getByText("Ethereum-formatted", {
|
56
|
+
exact: true,
|
57
|
+
selector: "span",
|
58
|
+
}),
|
59
|
+
).toBeInTheDocument(),
|
60
|
+
{ timeout: 2000 },
|
55
61
|
);
|
56
62
|
});
|
57
63
|
|
@@ -62,13 +68,15 @@ describe.runIf(process.env.TW_SECRET_KEY)("ChainName component", () => {
|
|
62
68
|
</ChainProvider>,
|
63
69
|
);
|
64
70
|
|
65
|
-
await waitFor(
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
71
|
+
await waitFor(
|
72
|
+
() =>
|
73
|
+
expect(
|
74
|
+
screen.getByText("oops", {
|
75
|
+
exact: true,
|
76
|
+
selector: "span",
|
77
|
+
}),
|
78
|
+
).toBeInTheDocument(),
|
79
|
+
{ timeout: 2000 },
|
72
80
|
);
|
73
81
|
});
|
74
82
|
|
@@ -4,7 +4,8 @@ import {
|
|
4
4
|
DROP1155_CONTRACT,
|
5
5
|
UNISWAPV3_FACTORY_CONTRACT,
|
6
6
|
} from "~test/test-contracts.js";
|
7
|
-
import {
|
7
|
+
import { getFunctionId } from "../../../../../utils/function-id.js";
|
8
|
+
import { fetchNftMedia, getQueryKey } from "./media.js";
|
8
9
|
|
9
10
|
describe.runIf(process.env.TW_SECRET_KEY)("NFTMedia", () => {
|
10
11
|
it("fetchNftMedia should work with ERC721", async () => {
|
@@ -74,4 +75,60 @@ describe.runIf(process.env.TW_SECRET_KEY)("NFTMedia", () => {
|
|
74
75
|
}),
|
75
76
|
).rejects.toThrowError("Failed to resolve NFT info");
|
76
77
|
});
|
78
|
+
|
79
|
+
it("getQueryKey should work without mediaResolver", () => {
|
80
|
+
expect(getQueryKey({ chainId: 1, tokenId: 1n })).toStrictEqual([
|
81
|
+
"_internal_nft_media_",
|
82
|
+
1,
|
83
|
+
"1",
|
84
|
+
{
|
85
|
+
resolver: undefined,
|
86
|
+
},
|
87
|
+
]);
|
88
|
+
});
|
89
|
+
|
90
|
+
it("getQueryKey should work with mediaResolver being an object", () => {
|
91
|
+
expect(
|
92
|
+
getQueryKey({
|
93
|
+
chainId: 1,
|
94
|
+
tokenId: 1n,
|
95
|
+
mediaResolver: {
|
96
|
+
src: "test",
|
97
|
+
poster: "test",
|
98
|
+
},
|
99
|
+
}),
|
100
|
+
).toStrictEqual([
|
101
|
+
"_internal_nft_media_",
|
102
|
+
1,
|
103
|
+
"1",
|
104
|
+
{
|
105
|
+
resolver: {
|
106
|
+
src: "test",
|
107
|
+
poster: "test",
|
108
|
+
},
|
109
|
+
},
|
110
|
+
]);
|
111
|
+
});
|
112
|
+
|
113
|
+
it("getQueryKey should work with mediaResolver being a function", () => {
|
114
|
+
const fn = () => ({
|
115
|
+
src: "test",
|
116
|
+
poster: "test",
|
117
|
+
});
|
118
|
+
const fnId = getFunctionId(fn);
|
119
|
+
expect(
|
120
|
+
getQueryKey({
|
121
|
+
chainId: 1,
|
122
|
+
tokenId: 1n,
|
123
|
+
mediaResolver: fn,
|
124
|
+
}),
|
125
|
+
).toStrictEqual([
|
126
|
+
"_internal_nft_media_",
|
127
|
+
1,
|
128
|
+
"1",
|
129
|
+
{
|
130
|
+
resolver: fnId,
|
131
|
+
},
|
132
|
+
]);
|
133
|
+
});
|
77
134
|
});
|
@@ -132,19 +132,11 @@ export function NFTMedia({
|
|
132
132
|
}: NFTMediaProps) {
|
133
133
|
const { contract, tokenId } = useNFTContext();
|
134
134
|
const mediaQuery = useQuery({
|
135
|
-
queryKey:
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
resolver:
|
141
|
-
typeof mediaResolver === "object"
|
142
|
-
? mediaResolver
|
143
|
-
: typeof mediaResolver === "function"
|
144
|
-
? getFunctionId(mediaResolver)
|
145
|
-
: undefined,
|
146
|
-
},
|
147
|
-
],
|
135
|
+
queryKey: getQueryKey({
|
136
|
+
chainId: contract.chain.id,
|
137
|
+
tokenId,
|
138
|
+
mediaResolver,
|
139
|
+
}),
|
148
140
|
queryFn: async (): Promise<NFTMediaInfo> =>
|
149
141
|
fetchNftMedia({ mediaResolver, contract, tokenId }),
|
150
142
|
...queryOptions,
|
@@ -168,6 +160,33 @@ export function NFTMedia({
|
|
168
160
|
);
|
169
161
|
}
|
170
162
|
|
163
|
+
/**
|
164
|
+
* @internal
|
165
|
+
*/
|
166
|
+
export function getQueryKey(props: {
|
167
|
+
chainId: number;
|
168
|
+
tokenId: bigint;
|
169
|
+
mediaResolver?:
|
170
|
+
| NFTMediaInfo
|
171
|
+
| (() => NFTMediaInfo)
|
172
|
+
| (() => Promise<NFTMediaInfo>);
|
173
|
+
}) {
|
174
|
+
const { chainId, tokenId, mediaResolver } = props;
|
175
|
+
return [
|
176
|
+
"_internal_nft_media_",
|
177
|
+
chainId,
|
178
|
+
tokenId.toString(),
|
179
|
+
{
|
180
|
+
resolver:
|
181
|
+
typeof mediaResolver === "object"
|
182
|
+
? mediaResolver
|
183
|
+
: typeof mediaResolver === "function"
|
184
|
+
? getFunctionId(mediaResolver)
|
185
|
+
: undefined,
|
186
|
+
},
|
187
|
+
] as const;
|
188
|
+
}
|
189
|
+
|
171
190
|
/**
|
172
191
|
* @internal Exported for tests only
|
173
192
|
*/
|
@@ -4,7 +4,8 @@ import {
|
|
4
4
|
DROP1155_CONTRACT,
|
5
5
|
UNISWAPV3_FACTORY_CONTRACT,
|
6
6
|
} from "~test/test-contracts.js";
|
7
|
-
import {
|
7
|
+
import { getFunctionId } from "../../../../../utils/function-id.js";
|
8
|
+
import { fetchNftName, getQueryKey } from "./name.js";
|
8
9
|
|
9
10
|
describe.runIf(process.env.TW_SECRET_KEY)("NFTName", () => {
|
10
11
|
it("fetchNftName should work with ERC721", async () => {
|
@@ -58,4 +59,39 @@ describe.runIf(process.env.TW_SECRET_KEY)("NFTName", () => {
|
|
58
59
|
}),
|
59
60
|
).rejects.toThrowError("Failed to resolve NFT info");
|
60
61
|
});
|
62
|
+
|
63
|
+
it("getQueryKey should work without nameResolver", () => {
|
64
|
+
expect(getQueryKey({ chainId: 1, tokenId: 1n })).toStrictEqual([
|
65
|
+
"_internal_nft_name_",
|
66
|
+
1,
|
67
|
+
"1",
|
68
|
+
{ resolver: undefined },
|
69
|
+
]);
|
70
|
+
});
|
71
|
+
|
72
|
+
it("getQueryKey should work with nameResolver being a string", () => {
|
73
|
+
expect(
|
74
|
+
getQueryKey({ chainId: 1, tokenId: 1n, nameResolver: "test" }),
|
75
|
+
).toStrictEqual(["_internal_nft_name_", 1, "1", { resolver: "test" }]);
|
76
|
+
});
|
77
|
+
|
78
|
+
it("getQueryKey should work with nameResolver being a () => string", () => {
|
79
|
+
const fn = () => "test";
|
80
|
+
const fnId = getFunctionId(fn);
|
81
|
+
expect(
|
82
|
+
getQueryKey({ chainId: 1, tokenId: 1n, nameResolver: fn }),
|
83
|
+
).toStrictEqual(["_internal_nft_name_", 1, "1", { resolver: fnId }]);
|
84
|
+
});
|
85
|
+
|
86
|
+
it("getQueryKey should work with nameResolver being a async () => string", () => {
|
87
|
+
const fn = async () => "test";
|
88
|
+
const fnId = getFunctionId(fn);
|
89
|
+
expect(
|
90
|
+
getQueryKey({
|
91
|
+
chainId: 1,
|
92
|
+
tokenId: 1n,
|
93
|
+
nameResolver: fn,
|
94
|
+
}),
|
95
|
+
).toStrictEqual(["_internal_nft_name_", 1, "1", { resolver: fnId }]);
|
96
|
+
});
|
61
97
|
});
|
@@ -94,19 +94,11 @@ export function NFTName({
|
|
94
94
|
const { contract, tokenId } = useNFTContext();
|
95
95
|
|
96
96
|
const nameQuery = useQuery({
|
97
|
-
queryKey:
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
resolver:
|
103
|
-
typeof nameResolver === "string"
|
104
|
-
? nameResolver
|
105
|
-
: typeof nameResolver === "function"
|
106
|
-
? getFunctionId(nameResolver)
|
107
|
-
: undefined,
|
108
|
-
},
|
109
|
-
],
|
97
|
+
queryKey: getQueryKey({
|
98
|
+
chainId: contract.chain.id,
|
99
|
+
tokenId,
|
100
|
+
nameResolver,
|
101
|
+
}),
|
110
102
|
queryFn: async (): Promise<string> =>
|
111
103
|
fetchNftName({ nameResolver, contract, tokenId }),
|
112
104
|
...queryOptions,
|
@@ -122,6 +114,30 @@ export function NFTName({
|
|
122
114
|
return <span {...restProps}>{nameQuery.data}</span>;
|
123
115
|
}
|
124
116
|
|
117
|
+
/**
|
118
|
+
* @internal
|
119
|
+
*/
|
120
|
+
export function getQueryKey(props: {
|
121
|
+
chainId: number;
|
122
|
+
tokenId: bigint;
|
123
|
+
nameResolver?: string | (() => string) | (() => Promise<string>);
|
124
|
+
}) {
|
125
|
+
const { chainId, tokenId, nameResolver } = props;
|
126
|
+
return [
|
127
|
+
"_internal_nft_name_",
|
128
|
+
chainId,
|
129
|
+
tokenId.toString(),
|
130
|
+
{
|
131
|
+
resolver:
|
132
|
+
typeof nameResolver === "string"
|
133
|
+
? nameResolver
|
134
|
+
: typeof nameResolver === "function"
|
135
|
+
? getFunctionId(nameResolver)
|
136
|
+
: undefined,
|
137
|
+
},
|
138
|
+
] as const;
|
139
|
+
}
|
140
|
+
|
125
141
|
/**
|
126
142
|
* @internal Exported for tests
|
127
143
|
*/
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
2
|
+
import { getMimeTypeFromUrl } from "../ui/MediaRenderer/mime/mime.js";
|
3
|
+
import { resolveMimeType } from "./resolveMimeType.js";
|
4
|
+
|
5
|
+
// Mock the getMimeTypeFromUrl function
|
6
|
+
vi.mock("../ui/MediaRenderer/mime/mime.js", () => ({
|
7
|
+
getMimeTypeFromUrl: vi.fn(),
|
8
|
+
}));
|
9
|
+
|
10
|
+
describe("resolveMimeType", () => {
|
11
|
+
beforeEach(() => {
|
12
|
+
vi.resetAllMocks();
|
13
|
+
});
|
14
|
+
|
15
|
+
it("should return undefined for empty URL", async () => {
|
16
|
+
const result = await resolveMimeType();
|
17
|
+
expect(result).toBeUndefined();
|
18
|
+
});
|
19
|
+
|
20
|
+
it("should return mime type from URL if available", async () => {
|
21
|
+
vi.mocked(getMimeTypeFromUrl).mockReturnValue("image/jpeg");
|
22
|
+
const result = await resolveMimeType("https://example.com/image.jpg");
|
23
|
+
expect(result).toBe("image/jpeg");
|
24
|
+
expect(getMimeTypeFromUrl).toHaveBeenCalledWith(
|
25
|
+
"https://example.com/image.jpg",
|
26
|
+
);
|
27
|
+
});
|
28
|
+
|
29
|
+
it("should fetch mime type from server if not available from URL", async () => {
|
30
|
+
vi.mocked(getMimeTypeFromUrl).mockReturnValue(null);
|
31
|
+
global.fetch = vi.fn().mockResolvedValue({
|
32
|
+
ok: true,
|
33
|
+
headers: new Headers({ "content-type": "application/json" }),
|
34
|
+
});
|
35
|
+
|
36
|
+
const result = await resolveMimeType("https://example.com/data.json");
|
37
|
+
expect(result).toBe("application/json");
|
38
|
+
expect(global.fetch).toHaveBeenCalledWith("https://example.com/data.json", {
|
39
|
+
method: "HEAD",
|
40
|
+
});
|
41
|
+
});
|
42
|
+
|
43
|
+
it("should return undefined if fetch fails", async () => {
|
44
|
+
vi.mocked(getMimeTypeFromUrl).mockReturnValue(null);
|
45
|
+
global.fetch = vi.fn().mockResolvedValue({
|
46
|
+
ok: false,
|
47
|
+
});
|
48
|
+
|
49
|
+
const result = await resolveMimeType("https://example.com/unknown");
|
50
|
+
expect(result).toBeUndefined();
|
51
|
+
});
|
52
|
+
|
53
|
+
it("should return undefined if content-type header is missing", async () => {
|
54
|
+
vi.mocked(getMimeTypeFromUrl).mockReturnValue(null);
|
55
|
+
global.fetch = vi.fn().mockResolvedValue({
|
56
|
+
ok: true,
|
57
|
+
headers: new Headers(),
|
58
|
+
});
|
59
|
+
|
60
|
+
const result = await resolveMimeType("https://example.com/noheader");
|
61
|
+
expect(result).toBeUndefined();
|
62
|
+
});
|
63
|
+
});
|
package/src/version.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const version = "5.80.
|
1
|
+
export const version = "5.80.1-nightly-ce3e850fdbf34911e20919ecc2674e4a63f08fa3-20241226000321";
|
@@ -247,11 +247,11 @@ export function createConnectionManager(storage: AsyncStorage) {
|
|
247
247
|
const switchActiveWalletChain = async (chain: Chain) => {
|
248
248
|
const wallet = activeWalletStore.getValue();
|
249
249
|
if (!wallet) {
|
250
|
-
throw new Error("
|
250
|
+
throw new Error("No active wallet found");
|
251
251
|
}
|
252
252
|
|
253
253
|
if (!wallet.switchChain) {
|
254
|
-
throw new Error("
|
254
|
+
throw new Error("Wallet does not support switching chains");
|
255
255
|
}
|
256
256
|
|
257
257
|
if (wallet.id === "smart") {
|
@@ -5,7 +5,7 @@ import { generateAccount } from "../utils/generateAccount.js";
|
|
5
5
|
import { connectSmartWallet, disconnectSmartWallet } from "./index.js";
|
6
6
|
import { smartWallet } from "./smart-wallet.js";
|
7
7
|
|
8
|
-
describe("Smart Wallet Index", () => {
|
8
|
+
describe.runIf(process.env.TW_SECRET_KEY)("Smart Wallet Index", () => {
|
9
9
|
const chain = defineChain(1); // Ethereum mainnet
|
10
10
|
const client = TEST_CLIENT;
|
11
11
|
|