Skip to content

Commit e4af888

Browse files
0237hYaroShkvorets
andauthoredFeb 11, 2025··
Use Sourcify v2 endpoint for contract lookups (#1957)
* Use Sourcify v2 endpoint for contract lookups * Fix lint * simplify sourcify error handling * add test, relax timeout values for init.test.ts --------- Co-authored-by: YaroShkvorets <shkvorets@gmail.com>
1 parent 33a7148 commit e4af888

File tree

4 files changed

+40
-27
lines changed

4 files changed

+40
-27
lines changed
 

‎.changeset/giant-owls-accept.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphprotocol/graph-cli': patch
3+
---
4+
5+
Use Sourcify v2 endpoint for contract lookups

‎packages/cli/src/command-helpers/contracts.test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ const TEST_SOURCIFY_CONTRACT_INFO = {
9393
startBlock: 10_736_242,
9494
},
9595
},
96+
'mainnet-non-verified': {
97+
'0x4a183b7ED67B9E14b3f45Abfb2Cf44ed22c29E54': {
98+
name: null,
99+
startBlock: null,
100+
},
101+
},
96102
optimism: {
97103
'0xc35DADB65012eC5796536bD9864eD8773aBc74C4': {
98104
name: 'BentoBoxV1',
@@ -111,6 +117,13 @@ const TEST_SOURCIFY_CONTRACT_INFO = {
111117
startBlock: null,
112118
},
113119
},
120+
// Invalid address (missing 0x)
121+
matic: {
122+
'0000000000000000000000000000000000000000': {
123+
name: null,
124+
startBlock: null,
125+
},
126+
},
114127
};
115128

116129
// Retry helper with configurable number of retries

‎packages/cli/src/command-helpers/contracts.ts

+20-25
Original file line numberDiff line numberDiff line change
@@ -163,37 +163,32 @@ export class ContractService {
163163
if (!network.caip2Id.startsWith('eip155'))
164164
throw new Error(`Invalid chainId, Sourcify API only supports EVM chains`);
165165

166+
if (!address.startsWith('0x') || address.length != 42)
167+
throw new Error(`Invalid address, must start with 0x prefix and be 20 bytes long`);
168+
166169
const chainId = network.caip2Id.split(':')[1];
167-
const url = `https://sourcify.dev/server/files/any/${chainId}/${address}`;
168-
const json:
169-
| {
170-
status: string;
171-
files: { name: string; path: string; content: string }[];
172-
}
173-
| { error: string } = await (
174-
await fetch(url).catch(error => {
175-
throw new Error(`Sourcify API is unreachable: ${error}`);
176-
})
177-
).json();
170+
const url = `https://sourcify.dev/server/v2/contract/${chainId}/${address}?fields=abi,compilation,deployment`;
171+
const resp = await fetch(url).catch(error => {
172+
throw new Error(`Sourcify API is unreachable: ${error}`);
173+
});
174+
if (resp.status === 404) throw new Error(`Sourcify API says contract is not verified`);
175+
if (!resp.ok) throw new Error(`Sourcify API returned status ${resp.status}`);
176+
const json: {
177+
abi: any[];
178+
compilation: { name: string };
179+
deployment: { blockNumber: string };
180+
} = await resp.json();
178181

179182
if (json) {
180-
if ('error' in json) throw new Error(`Sourcify API error: ${json.error}`);
181-
182-
let metadata: any = json.files.find(e => e.name === 'metadata.json')?.content;
183-
if (!metadata) throw new Error('Contract is missing metadata');
184-
185-
const tx_hash = json.files.find(e => e.name === 'creator-tx-hash.txt')?.content;
186-
if (!tx_hash) throw new Error('Contract is missing tx creation hash');
183+
const abi = json.abi;
184+
const contractName = json.compilation?.name;
185+
const blockNumber = json.deployment?.blockNumber;
187186

188-
const tx = await this.fetchTransactionByHash(networkId, tx_hash);
189-
if (!tx?.blockNumber)
190-
throw new Error(`Can't fetch blockNumber from tx: ${JSON.stringify(tx)}`);
187+
if (!abi || !contractName || !blockNumber) throw new Error('Contract is missing metadata');
191188

192-
metadata = JSON.parse(metadata);
193-
const contractName = Object.values(metadata.settings.compilationTarget)[0] as string;
194189
return {
195-
abi: new ABICtor(contractName, undefined, immutable.fromJS(metadata.output.abi)) as ABI,
196-
startBlock: Number(tx.blockNumber).toString(),
190+
abi: new ABICtor(contractName, undefined, immutable.fromJS(abi)) as ABI,
191+
startBlock: Number(blockNumber).toString(),
197192
name: contractName,
198193
};
199194
}

‎packages/cli/tests/cli/init.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe(
88
'Init',
99
{
1010
sequential: true,
11-
timeout: 100_000,
11+
timeout: 500_000,
1212
},
1313
() => {
1414
const baseDir = path.join(__dirname, 'init');
@@ -31,7 +31,7 @@ describe(
3131
path.join('init', 'ethereum', 'from-example'),
3232
{
3333
exitCode: 0,
34-
timeout: 100_000,
34+
timeout: 200_000,
3535
cwd: ethereumBaseDir,
3636
deleteDir: true,
3737
},

0 commit comments

Comments
 (0)
Please sign in to comment.