Skip to content

Commit a99f7f6

Browse files
authored
Merge branch 'master' into yann300-patch-66
2 parents 24f7519 + 6637de6 commit a99f7f6

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

libs/remix-core-plugin/src/lib/helpers/fetch-etherscan.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,52 @@ export const fetchContractFromEtherscan = async (plugin, endpoint: string | Netw
1111
if (!etherscanKey) etherscanKey = '2HKUX5ZVASZIKWJM8MIQVCRUVZ6JAWT531'
1212

1313
if (etherscanKey) {
14+
// Extract chain ID and build endpoint string once
15+
let chainId = 1 // Default to Ethereum mainnet
16+
let endpointStr: string
1417
if (typeof endpoint === 'object' && endpoint !== null && 'id' in endpoint && 'name' in endpoint) {
15-
endpoint = endpoint.id == 1 ? 'api.etherscan.io' : 'api-' + endpoint.name + '.etherscan.io'
18+
chainId = endpoint.id
19+
const normalized = String(endpoint.name || '').toLowerCase()
20+
endpointStr = endpoint.id == 1 ? 'api.etherscan.io' : 'api-' + normalized + '.etherscan.io'
21+
} else {
22+
endpointStr = endpoint as string
1623
}
1724
try {
18-
data = await fetch('https://' + endpoint + '/api?module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey)
19-
data = await data.json()
25+
// Prefer central V2 API host with chainid param (works across Etherscan-supported networks)
26+
const v2CentralUrl = 'https://api.etherscan.io/v2/api?chainid=' + chainId + '&module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
27+
let response = await fetch(v2CentralUrl)
28+
const centralV2Status = response.status;
29+
const centralV2StatusText = response.statusText;
30+
31+
// If central V2 not OK, try per-network V2, then per-network V1
32+
if (!response.ok) {
33+
const v2PerNetworkUrl = 'https://' + endpointStr + '/v2/api?chainid=' + chainId + '&module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
34+
const v2PerNetworkResponse = await fetch(v2PerNetworkUrl)
35+
const v2PerNetworkStatus = v2PerNetworkResponse.status;
36+
const v2PerNetworkStatusText = v2PerNetworkResponse.statusText;
37+
if (v2PerNetworkResponse.ok) {
38+
response = v2PerNetworkResponse;
39+
} else {
40+
const v1Url = 'https://' + endpointStr + '/api?module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
41+
const v1Response = await fetch(v1Url)
42+
const v1Status = v1Response.status;
43+
const v1StatusText = v1Response.statusText;
44+
if (v1Response.ok) {
45+
response = v1Response;
46+
} else {
47+
// All three endpoints failed, throw a descriptive error
48+
throw new Error(
49+
`All Etherscan API endpoints failed:\n` +
50+
`Central V2: ${v2CentralUrl} [${centralV2Status} ${centralV2StatusText}]\n` +
51+
`Per-network V2: ${v2PerNetworkUrl} [${v2PerNetworkStatus} ${v2PerNetworkStatusText}]\n` +
52+
`Per-network V1: ${v1Url} [${v1Status} ${v1StatusText}]`
53+
);
54+
}
55+
}
56+
}
57+
58+
data = await response.json()
59+
2060
// etherscan api doc https://docs.etherscan.io/api-endpoints/contracts
2161
if (data.message === 'OK' && data.status === "1") {
2262
if (data.result.length) {

libs/remix-ui/remix-ai-assistant/src/components/prompt.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export interface PromptAreaProps {
4040
maximizePanel: () => Promise<void>
4141
aiMode: 'ask' | 'edit'
4242
setAiMode: React.Dispatch<React.SetStateAction<'ask' | 'edit'>>
43+
isMaximized: boolean
44+
setIsMaximized: React.Dispatch<React.SetStateAction<boolean>>
4345
}
4446

4547
const _paq = (window._paq = window._paq || [])
@@ -77,7 +79,9 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
7779
textareaRef,
7880
maximizePanel,
7981
aiMode,
80-
setAiMode
82+
setAiMode,
83+
isMaximized,
84+
setIsMaximized
8185
}) => {
8286

8387
return (
@@ -155,7 +159,9 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
155159
value={input}
156160
disabled={isStreaming}
157161
onFocus={() => {
158-
maximizePanel()
162+
if (!isMaximized) {
163+
maximizePanel()
164+
}
159165
}}
160166
onChange={e => {
161167
setInput(e.target.value)

libs/remix-ui/remix-ai-assistant/src/components/remix-ui-remix-ai-assistant.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
5353
const [isOllamaFailureFallback, setIsOllamaFailureFallback] = useState(false)
5454
const [aiMode, setAiMode] = useState<'ask' | 'edit'>('ask')
5555
const [themeTracker, setThemeTracker] = useState(null)
56+
const [isMaximized, setIsMaximized] = useState(false)
5657

5758
const historyRef = useRef<HTMLDivElement | null>(null)
5859
const modelBtnRef = useRef(null)
@@ -666,6 +667,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
666667

667668
const maximizePanel = async () => {
668669
await props.plugin.call('layout', 'maximisePinnedPanel')
670+
setIsMaximized(true) // ensured that expansion of the panel is stateful
669671
}
670672

671673
return (
@@ -759,6 +761,8 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
759761
textareaRef={textareaRef}
760762
aiMode={aiMode}
761763
setAiMode={setAiMode}
764+
isMaximized={isMaximized}
765+
setIsMaximized={setIsMaximized}
762766
/>
763767
</section>
764768
</div>

0 commit comments

Comments
 (0)