@@ -21,19 +21,17 @@ const IS_ONLINE = true; // Treat this as a toggle for development.
2121let fileSearchProviderDisposable : Disposable | undefined ;
2222let textSearchProviderDisposable : Disposable | undefined ;
2323
24- export interface OpenContractSourceArgs {
25- fs : FileSystem ;
26- apiName : explorer . ApiName ;
27- address : string ;
28- }
29-
3024export async function openContractSource (
3125 context : ExtensionContext ,
32- args : OpenContractSourceArgs
33- ) {
34- const [ entries , info ] = await saveContractFilesToFs ( args ) ;
35-
36- const mainFile = getMainContractFile ( entries , info ) ;
26+ fs : FileSystem ,
27+ apiName : explorer . ApiName ,
28+ address : string
29+ ) : Promise < string > {
30+ const { entries, mainFile, contractName } = await saveContractFilesToFs (
31+ fs ,
32+ apiName ,
33+ address
34+ ) ;
3735
3836 fileSearchProviderDisposable ?. dispose ( ) ;
3937 fileSearchProviderDisposable = workspace . registerFileSearchProvider (
@@ -51,47 +49,93 @@ export async function openContractSource(
5149
5250 await showTextDocument ( mainFile ) ;
5351
54- return info ;
52+ return contractName ;
53+ }
54+
55+ async function saveContractFilesToFs (
56+ fs : FileSystem ,
57+ apiName : explorer . ApiName ,
58+ address : string
59+ ) {
60+ if ( address . includes ( "," ) ) {
61+ const addresses = address . split ( "," ) ;
62+ const results = await Promise . all (
63+ addresses . map ( ( a ) =>
64+ saveSingleContractFilesToFs ( fs , apiName , a , {
65+ prefix : a + "/" ,
66+ allowProxies : false ,
67+ includeMainInfo : true ,
68+ } )
69+ )
70+ ) ;
71+ return {
72+ entries : results . flatMap ( ( r ) => r . entries ) ,
73+ mainFile : results [ 0 ] . mainFile ,
74+ contractName : results [ 0 ] . contractName ,
75+ } ;
76+ }
77+ return saveSingleContractFilesToFs ( fs , apiName , address , {
78+ allowProxies : true ,
79+ includeMainInfo : false ,
80+ } ) ;
5581}
5682
57- async function saveContractFilesToFs ( {
58- fs,
59- address,
60- apiName,
61- } : OpenContractSourceArgs ) {
83+ async function saveSingleContractFilesToFs (
84+ fs : FileSystem ,
85+ apiName : explorer . ApiName ,
86+ address : string ,
87+ options : {
88+ prefix ?: string ;
89+ allowProxies : boolean ;
90+ includeMainInfo : boolean ;
91+ }
92+ ) {
6293 let result : explorer . FetchFilesResult ;
6394
6495 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
6596 if ( IS_ONLINE ) {
66- result = await explorer . fetchFiles ( apiName , address ) ;
97+ result = await explorer . fetchFiles ( apiName , address , {
98+ proxyDepth : options . allowProxies ? undefined : 0 ,
99+ skipPrefix : ! ! options . prefix ,
100+ } ) ;
67101 } else {
68102 result = fixtures . etherscanResult ;
69103 }
70104
105+ const withPrefix = ( file : string ) =>
106+ options . prefix ? options . prefix + file : file ;
107+
71108 const entries = Object . entries ( result . files ) ;
72109 for ( const [ path , content ] of entries ) {
73- fs . writeFile ( path , content ) ;
110+ fs . writeFile ( withPrefix ( path ) , content ) ;
74111 }
75112
76- return [ entries , result . info ] as const ;
113+ const mainFile = getMainContractFile ( entries , result . info ) ;
114+
115+ if ( options . includeMainInfo ) {
116+ fs . writeFile ( withPrefix ( "main.md" ) , `Main file: ${ mainFile } ` ) ;
117+ }
118+
119+ return {
120+ entries,
121+ mainFile : withPrefix ( mainFile ) ,
122+ contractName : result . info . ContractName ?? "contract" ,
123+ } ;
77124}
78125
79126function getMainContractFile (
80- files : [ string , ... unknown [ ] ] [ ] ,
127+ files : [ string , string ] [ ] ,
81128 info : explorer . FetchFilesResult [ "info" ]
82129) : string {
83130 const ext = fileExtension ( info ) ;
131+ const name = info . implementation ?. ContractName ?? info . ContractName ;
84132
85- let fileToShow =
86- info . implementation &&
87- files . find ( ( [ path ] ) =>
88- path . endsWith ( `/${ info . implementation ! . ContractName } ${ ext } ` )
89- ) ;
133+ let fileToShow = files . find ( ( [ path ] ) => path . endsWith ( `/${ name } ${ ext } ` ) ) ;
90134
91- if ( ! fileToShow )
92- fileToShow = files . find ( ( [ path ] ) =>
93- path . endsWith ( `/ ${ info . ContractName } ${ ext } ` )
94- ) ;
135+ if ( ! fileToShow ) {
136+ const regexp = new RegExp ( `contract\\s+ ${ name } ` ) ;
137+ fileToShow = files . find ( ( [ path , source ] ) => regexp . test ( source ) ) ;
138+ }
95139
96140 if ( ! fileToShow ) fileToShow = files . sort ( byPathLength ) [ 0 ] ;
97141
0 commit comments