Skip to content

Commit 4f7fe09

Browse files
committed
fix: lint the ui playground
1 parent 2302040 commit 4f7fe09

21 files changed

+1050
-1312
lines changed

playground/multichain-react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@types/chrome": "^0.0.279",
6363
"@types/jest": "^28.1.6",
6464
"@types/node": "^18.18",
65+
"@types/react": "^19.1.8",
6566
"@yarnpkg/types": "^4.0.0-rc.52",
6667
"autoprefixer": "^10.4.21",
6768
"buffer": "^6.0.3",
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { render, screen } from '@testing-library/react';
1+
import { render, screen } from "@testing-library/react";
22

3-
import App from './App';
3+
import App from "./App";
44

5-
test('renders learn react link', () => {
6-
render(<App />);
7-
const linkElement = screen.getByText(/MetaMask MultiChain/iu);
8-
expect(linkElement).toBeInTheDocument();
5+
test("renders learn react link", () => {
6+
render(<App />);
7+
const linkElement = screen.getByText(/MetaMask MultiChain/iu);
8+
expect(linkElement).toBeInTheDocument();
99
});
Lines changed: 110 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React, { useId } from "react";
12
import { useCallback, useEffect, useState } from "react";
23
import { Scope, SessionData } from "@metamask/multichain-sdk";
34
import { CaipAccountId } from "@metamask/utils";
@@ -7,144 +8,116 @@ import DynamicInputs, { INPUT_LABEL_TYPE } from "./components/DynamicInputs";
78
import { FEATURED_NETWORKS } from "./constants/networks";
89
import { ScopeCard } from "./components/ScopeCard";
910

10-
11-
12-
1311
function App() {
14-
const [customScopes, setCustomScopes] = useState<string[]>(["eip155:1"]);
15-
const [caipAccountIds, setCaipAccountIds] = useState<CaipAccountId[]>([]);
16-
const [extensionId, setExtensionId] = useState<string>(METAMASK_PROD_CHROME_ID);
17-
18-
const {
19-
isConnected,
20-
session,
21-
connect: sdkConnect,
22-
disconnect: sdkDisconnect,
23-
} = useSDK({
24-
extensionId,
25-
});
26-
27-
useEffect(() => {
28-
if (session) {
29-
const scopes = Object.keys(session.sessionScopes);
30-
setCustomScopes(scopes);
31-
32-
// Accumulate all accounts from all scopes
33-
const allAccounts: CaipAccountId[] = [];
34-
for (const scope of scopes) {
35-
const { accounts } = session.sessionScopes[scope as keyof typeof session.sessionScopes] ?? {};
36-
if (accounts) {
37-
allAccounts.push(...accounts);
38-
}
39-
}
40-
setCaipAccountIds(allAccounts);
41-
}
42-
}, [session])
43-
44-
// Check if current scope selection differs from connected session scopes
45-
const scopesHaveChanged = () => {
46-
if (!session) return false;
47-
const sessionScopes = Object.keys(session.sessionScopes);
48-
const currentScopes = customScopes.filter(scope => scope.length);
49-
50-
if (sessionScopes.length !== currentScopes.length) return true;
51-
52-
return !sessionScopes.every(scope => currentScopes.includes(scope)) ||
53-
!currentScopes.every(scope => sessionScopes.includes(scope));
54-
};
55-
56-
const connect = async () => {
57-
try {
58-
const selectedScopesArray = customScopes.filter((scope) => scope.length)
59-
const filteredAccountIds = caipAccountIds.filter((addr) => addr.trim() !== "");
60-
await sdkConnect(
61-
selectedScopesArray as Scope[],
62-
filteredAccountIds as CaipAccountId[],
63-
);
64-
} catch (error) {
65-
console.error("Error creating session:", error);
66-
}
67-
}
68-
69-
const disconnect = useCallback(async () => {
70-
await sdkDisconnect()
71-
}, [sdkDisconnect])
72-
73-
const availableOptions = Object.keys(FEATURED_NETWORKS).reduce<{ name: string, value: string }[]>((all, networkName) => {
74-
const networkCaipValue = FEATURED_NETWORKS[networkName as keyof typeof FEATURED_NETWORKS];
75-
return [
76-
...all,
77-
{ name: networkName, value: networkCaipValue, }
78-
];
79-
}, [])
80-
81-
82-
83-
84-
85-
return (
86-
<div className="min-h-screen bg-gray-50 flex justify-center">
87-
<div className="max-w-6xl w-full p-8">
88-
<h1 className="text-slate-800 text-4xl font-bold mb-8 text-center">
89-
MetaMask MultiChain API Test Dapp
90-
</h1>
91-
<section className="bg-white rounded-lg p-8 mb-6 shadow-sm">
92-
<label className="flex flex-col gap-2 mb-4">
93-
<span className="text-gray-700 font-medium">Extension ID:</span>
94-
<input
95-
type="text"
96-
placeholder="Enter extension ID"
97-
value={extensionId}
98-
onChange={(evt) => setExtensionId(evt.target.value)}
99-
disabled={true}
100-
readOnly={true}
101-
data-testid="extension-id-input"
102-
id="extension-id-input"
103-
className="p-2 border border-gray-300 rounded text-base bg-gray-50"
104-
/>
105-
</label>
106-
<div className="mb-4">
107-
<DynamicInputs
108-
availableOptions={availableOptions}
109-
inputArray={customScopes}
110-
setInputArray={setCustomScopes}
111-
label={INPUT_LABEL_TYPE.SCOPE}
112-
/>
113-
</div>
114-
{(!isConnected || scopesHaveChanged()) && (
115-
<button
116-
onClick={connect}
117-
className="bg-blue-500 text-white px-5 py-2 rounded text-base mr-2 hover:bg-blue-600 transition-colors"
118-
>
119-
{isConnected && scopesHaveChanged() ? "Re Establish Connection" : "Connect"}
120-
</button>
121-
)}
122-
{
123-
isConnected && (
124-
<button
125-
onClick={disconnect}
126-
className="bg-blue-500 text-white px-5 py-2 rounded text-base hover:bg-blue-600 transition-colors"
127-
>
128-
Disconnect
129-
</button>
130-
)
131-
}
132-
</section>
133-
<section className="bg-white rounded-lg p-8 mb-6 shadow-sm">
134-
{Object.keys(session?.sessionScopes ?? {}).length > 0 && (
135-
<section className="mb-6">
136-
<h2 className="text-2xl font-bold text-gray-800 mb-6">Connected Networks</h2>
137-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
138-
{Object.entries(session?.sessionScopes ?? {}).map(([scope, details]) => {
139-
return <ScopeCard key={scope} scope={scope as Scope} details={details as SessionData['sessionScopes'][Scope]} />
140-
})}
141-
</div>
142-
</section>
143-
)}
144-
</section>
145-
</div>
146-
</div>
147-
);
12+
const id = useId();
13+
const [customScopes, setCustomScopes] = useState<string[]>(["eip155:1"]);
14+
const [caipAccountIds, setCaipAccountIds] = useState<CaipAccountId[]>([]);
15+
const [extensionId, setExtensionId] = useState<string>(METAMASK_PROD_CHROME_ID);
16+
17+
const {
18+
isConnected,
19+
session,
20+
connect: sdkConnect,
21+
disconnect: sdkDisconnect,
22+
} = useSDK({
23+
extensionId,
24+
});
25+
26+
useEffect(() => {
27+
if (session) {
28+
const scopes = Object.keys(session.sessionScopes);
29+
setCustomScopes(scopes);
30+
31+
// Accumulate all accounts from all scopes
32+
const allAccounts: CaipAccountId[] = [];
33+
for (const scope of scopes) {
34+
const { accounts } = session.sessionScopes[scope as keyof typeof session.sessionScopes] ?? {};
35+
if (accounts) {
36+
allAccounts.push(...accounts);
37+
}
38+
}
39+
setCaipAccountIds(allAccounts);
40+
}
41+
}, [session]);
42+
43+
// Check if current scope selection differs from connected session scopes
44+
const scopesHaveChanged = () => {
45+
if (!session) return false;
46+
const sessionScopes = Object.keys(session.sessionScopes);
47+
const currentScopes = customScopes.filter((scope) => scope.length);
48+
49+
if (sessionScopes.length !== currentScopes.length) return true;
50+
51+
return !sessionScopes.every((scope) => currentScopes.includes(scope)) || !currentScopes.every((scope) => sessionScopes.includes(scope));
52+
};
53+
54+
const connect = async () => {
55+
try {
56+
const selectedScopesArray = customScopes.filter((scope) => scope.length);
57+
const filteredAccountIds = caipAccountIds.filter((addr) => addr.trim() !== "");
58+
await sdkConnect(selectedScopesArray as Scope[], filteredAccountIds as CaipAccountId[]);
59+
} catch (error) {
60+
console.error("Error creating session:", error);
61+
}
62+
};
63+
64+
const disconnect = useCallback(async () => {
65+
await sdkDisconnect();
66+
}, [sdkDisconnect]);
67+
68+
const availableOptions = Object.keys(FEATURED_NETWORKS).reduce<{ name: string; value: string }[]>((all, networkName) => {
69+
const networkCaipValue = FEATURED_NETWORKS[networkName as keyof typeof FEATURED_NETWORKS];
70+
return [...all, { name: networkName, value: networkCaipValue }];
71+
}, []);
72+
73+
return (
74+
<div className="min-h-screen bg-gray-50 flex justify-center">
75+
<div className="max-w-6xl w-full p-8">
76+
<h1 className="text-slate-800 text-4xl font-bold mb-8 text-center">MetaMask MultiChain API Test Dapp</h1>
77+
<section className="bg-white rounded-lg p-8 mb-6 shadow-sm">
78+
<label className="flex flex-col gap-2 mb-4">
79+
<span className="text-gray-700 font-medium">Extension ID:</span>
80+
<input
81+
type="text"
82+
placeholder="Enter extension ID"
83+
value={extensionId}
84+
onChange={(evt) => setExtensionId(evt.target.value)}
85+
disabled={true}
86+
readOnly={true}
87+
data-testid="extension-id-input"
88+
id={id}
89+
className="p-2 border border-gray-300 rounded text-base bg-gray-50"
90+
/>
91+
</label>
92+
<div className="mb-4">
93+
<DynamicInputs availableOptions={availableOptions} inputArray={customScopes} setInputArray={setCustomScopes} label={INPUT_LABEL_TYPE.SCOPE} />
94+
</div>
95+
{(!isConnected || scopesHaveChanged()) && (
96+
<button type="button" onClick={connect} className="bg-blue-500 text-white px-5 py-2 rounded text-base mr-2 hover:bg-blue-600 transition-colors">
97+
{isConnected && scopesHaveChanged() ? "Re Establish Connection" : "Connect"}
98+
</button>
99+
)}
100+
{isConnected && (
101+
<button type="button" onClick={disconnect} className="bg-blue-500 text-white px-5 py-2 rounded text-base hover:bg-blue-600 transition-colors">
102+
Disconnect
103+
</button>
104+
)}
105+
</section>
106+
<section className="bg-white rounded-lg p-8 mb-6 shadow-sm">
107+
{Object.keys(session?.sessionScopes ?? {}).length > 0 && (
108+
<section className="mb-6">
109+
<h2 className="text-2xl font-bold text-gray-800 mb-6">Connected Networks</h2>
110+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
111+
{Object.entries(session?.sessionScopes ?? {}).map(([scope, details]) => {
112+
return <ScopeCard key={scope} scope={scope as Scope} details={details as SessionData["sessionScopes"][Scope]} />;
113+
})}
114+
</div>
115+
</section>
116+
)}
117+
</section>
118+
</div>
119+
</div>
120+
);
148121
}
149122

150123
export default App;

0 commit comments

Comments
 (0)