Skip to content

Commit 3c4e8b9

Browse files
committed
feat: support loading types from ethPM Manifest
1 parent 82f44ee commit 3c4e8b9

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

vyper/cli/utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,20 @@
99
def get_interface_file_path(base_paths: Sequence, import_path: str) -> Path:
1010
relative_path = Path(import_path)
1111
for path in base_paths:
12+
# Find ABI JSON files
1213
file_path = path.joinpath(relative_path)
1314
suffix = next((i for i in (".vy", ".json") if file_path.with_suffix(i).exists()), None)
1415
if suffix:
1516
return file_path.with_suffix(suffix)
17+
18+
# Find ethPM Manifest files (`from path.to.Manifest import InterfaceName`)
19+
# NOTE: Use file parent because this assumes that `file_path`
20+
# coincides with an ABI interface file
21+
file_path = file_path.parent
22+
suffix = next((i for i in (".vy", ".json") if file_path.with_suffix(i).exists()), None)
23+
if suffix:
24+
return file_path.with_suffix(suffix)
25+
1626
raise FileNotFoundError(f" Cannot locate interface '{import_path}{{.vy,.json}}'")
1727

1828

vyper/cli/vyper_compile.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,36 @@ def get_interface_codes(root_path: Path, contract_sources: ContractCodes) -> Dic
217217
with valid_path.open() as fh:
218218
code = fh.read()
219219
if valid_path.suffix == ".json":
220-
interfaces[file_path][interface_name] = {
221-
"type": "json",
222-
"code": json.loads(code.encode()),
223-
}
220+
contents = json.loads(code.encode())
221+
222+
# EthPM Manifest (EIP-2678)
223+
if "contractTypes" in contents:
224+
if (
225+
interface_name not in contents["contractTypes"]
226+
or "abi" not in contents["contractTypes"][interface_name]
227+
):
228+
raise ValueError(
229+
f"Could not find interface '{interface_name}'"
230+
f" in manifest '{valid_path}'."
231+
)
232+
233+
interfaces[file_path][interface_name] = {
234+
"type": "json",
235+
"code": contents["contractTypes"][interface_name]["abi"],
236+
}
237+
238+
# ABI JSON file (either `List[ABI]` or `{"abi": List[ABI]}`)
239+
elif isinstance(contents, list) or (
240+
"abi" in contents and isinstance(contents["abi"], list)
241+
):
242+
interfaces[file_path][interface_name] = {
243+
"type": "json",
244+
"code": contents,
245+
}
246+
247+
else:
248+
raise ValueError(f"Corrupted file: '{valid_path}'")
249+
224250
else:
225251
interfaces[file_path][interface_name] = {"type": "vyper", "code": code}
226252

0 commit comments

Comments
 (0)