Skip to content

Commit

Permalink
refactor: project
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Apr 12, 2024
1 parent 60d2829 commit 48cbf01
Show file tree
Hide file tree
Showing 88 changed files with 5,162 additions and 4,978 deletions.
5 changes: 4 additions & 1 deletion docs/userguides/accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,12 @@ Here is an example with custom EIP-712 classes:
from ape import accounts
from eip712.messages import EIP712Message, EIP712Type


class Person(EIP712Type):
name: "string"
wallet: "address"


class Mail(EIP712Message):
_chainId_: "uint256" = 1
_name_: "string" = "Ether Mail"
Expand All @@ -292,7 +294,8 @@ class Mail(EIP712Message):
sender: Person
receiver: Person

alice = Person(name="Alice", wallet="0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826")

alice = Person(name="Alice", wallet="0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826")
bob = Person("Bob", "0xB0B0b0b0b0b0B000000000000000000000000000")
message = Mail(sender=alice, receiver=bob)

Expand Down
31 changes: 18 additions & 13 deletions docs/userguides/clis.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,20 @@ In Ape, it is easy to extend the CLI context object and use the extended version
from ape.cli import ApeCliContextObject, ape_cli_context
import click


class MyManager:
"""My custom manager."""
"""My custom manager."""


class CustomContext(ApeCliContextObject):
"""Add new managers to your custom context"""
my_manager: MyManager = MyManager()

@property
def signer(self):
"""Utilize existing managers in your custom context."""
return self.account_manager.load("my_account")
"""Add new managers to your custom context"""
my_manager: MyManager = MyManager()

@property
def signer(self):
"""Utilize existing managers in your custom context."""
return self.account_manager.load("my_account")


@click.command()
@ape_cli_context(obj_type=CustomContext)
Expand Down Expand Up @@ -203,17 +206,19 @@ from ape_accounts.accounts import KeyfileAccount
# NOTE: This is just an example and not anything specific or recommended.
APPLICATION_PREFIX = "<FOO_BAR>"


@click.command()
@existing_alias_argument(account_type=KeyfileAccount)
def cli_0(alias):
pass

pass


@click.command()
@existing_alias_argument(account_type=lambda a: a.alias.startswith(APPLICATION_PREFIX))
def cli_1(alias):
pass
pass


# Select from the given accounts directly.
my_accounts = [accounts.load("me"), accounts.load("me2")]
selected_account = get_user_selected_account(account_type=my_accounts)
Expand Down
60 changes: 34 additions & 26 deletions docs/userguides/compile.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,24 @@ If your project includes Solidity (`.sol`) or Vyper (`.vy`) files, you will have
To include additional compilers in your project, you can add the plugins to the `plugins` list in your `ape-config.yaml` or install them using the CLI.
For information on how to configure plugins in your project, follow [this guide](./installing_plugins.html).

## Ignore Files
## Exclude Files

You can configure files to be ignored from compilation.
By default, Ape ignores files `package.json`, `package-lock.json`, `tsconfig.json`.
To override this list, edit your `ape-config.yaml` similarly:
You can configure files to be excluded from compilation.
By default, Ape excludes known non-contract files such as `package.json`, `package-lock.json`, `tsconfig.json`, or `.DS_Store`.
To append file-globs to the exclusions list, edit your `compile:exclude` config like this:

```yaml
compile:
exclude:
- "*package.json"
- "*package-lock.json"
- "*tsconfig.json"
- "*custom.json" # Append a custom ignore
- "examples" # Exclude all files in the examples/ directory
- "*Mock.sol" # Exclude all files ending in Mock.sol
```
**NOTE**: You must include the defaults in the list when overriding if you wish to retain them.
You can also exclude files using the `--config-override` CLI option:

```shell
ape compile --config-override '{"compile": {"exclude": ["*Mock.sol"]}}'
```

## Dependencies

Expand All @@ -85,30 +87,22 @@ compile:
## Settings

Generally, configure compiler plugins using your `ape-config.yaml` file.
One setting that applies to many compiler plugins is `cache_folder`, which holds dependency source files the compiler uses when compiling your contracts.
By default, the folder is in your `contracts/.cache` folder but there are times you may want to move this to another location.
Paths are relative to the project directory.
For instance, to move the dependency cahce to the root project directory:

```yaml
compile:
cache_folder: .cache
```

```{caution}
Changing the location of the dependency cache folder may alter the the output bytecode of your contracts from some compilers.
Specifically, the [solc compiler will apend a hash of the input metadata to the contract bytecode](https://docs.soliditylang.org/en/latest/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode) which will change with contract path or compiler settings changes.
This may impact things like contract verification on existing projects.
```

As another example, when using the `vyper` plugin, you can configure settings under the `vyper` key:
For example, when using the `vyper` plugin, you can configure settings under the `vyper` key:

```yaml
vyper:
version: 0.3.10
```

You can also configure adhoc settings in Python code:
When using the CLI, you can also specify settings using the `--config-override`.
This is not limited to compiler settings; you can include other settings, such as `"contracts_folder"`, which affects compiling.

```shell
ape compile --config-override '{"contracts_folder": "other_contracts", "vyper": {"evm_version": "paris"}, "solidity": {"evm_version": "paris"}}'
```

Finally, you can also configure settings in Python code:

```python
from pathlib import Path
Expand Down Expand Up @@ -149,3 +143,17 @@ owner = accounts.test_accounts[0]
instance = container.deploy(sender=owner)
```

## Output Extra

Sometimes, there are extra output styles you may want.
For example, to output minified ABI JSONs, use the following config:

```yaml
compile:
output_extra:
- ABI
```

Then, after compiling, you should notice minified ABI json files in your `.build/abi` folder.
This is useful if hosting these files on a web-server.
7 changes: 3 additions & 4 deletions docs/userguides/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ Here is an example of how you can use the multicall module:
import ape
from ape_ethereum import multicall


ADDRESSES = ("0xF4b8A02D4e8D76070bD7092B54D2cBbe90fa72e9", "0x80067013d7F7aF4e86b3890489AcAFe79F31a4Cb")
POOLS = [ape.project.IPool.at(a) for a in ADDRESSES]

Expand All @@ -409,14 +408,14 @@ def main():
call = multicall.Call()
for pool in POOLS:
call.add(pool.getReserves)

print(list(call()))

# Use multi-transaction.
tx = multicall.Transaction()
for pool in POOLS:
tx.add(pool.ApplyDiscount, 123)

acct = ape.accounts.load("signer")
for result in tx(sender=acct):
print(result)
Expand Down
7 changes: 4 additions & 3 deletions docs/userguides/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ Each account within ape will also fetch and store transactional data that you ca
To work with an account's transaction data, you can do stuff like this:

```python
In [1]: chain.history["example.eth"].query("value").sum() # All value sent by this address
In [2]: acct = accounts.load("my-acct"); acct.history[-1] # Last txn `acct` made
In [3]: acct.history.query("total_fees_paid").sum() # Sum of ether paid for fees by `acct`
In[1]: chain.history["example.eth"].query("value").sum() # All value sent by this address
In[2]: acct = accounts.load("my-acct");
acct.history[-1] # Last txn `acct` made
In[3]: acct.history.query("total_fees_paid").sum() # Sum of ether paid for fees by `acct`
```

## Getting Contract Event Data
Expand Down
21 changes: 14 additions & 7 deletions docs/userguides/dependencies.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dependencies

Ape downloads and caches dependencies in the `.ape/packages/<name>/<version-id>` directory where `<name>` refers to the name of the dependency and `<version-id>` refers to the version or branch of the package.
Ape downloads and caches dependencies in the `.ape/packages/projects/<name>/<version-id>` directory where `<name>` refers to the name of the dependency and `<version-id>` refers to the version or branch of the package.
When first downloading dependencies, Ape only places the source contents in the `sources` field of the `PackageManifest` and leaves the `contract_types` field untouched.
This is because dependencies may not compile by Ape's standard out-of-the-box but their contract types can still be used in projects that do.

Expand Down Expand Up @@ -141,25 +141,25 @@ For `npm` dependencies, you use an `npm:` prefix.
For local dependencies, you give it a path to the local dependency.
`--version` is not required when using a local dependency.

### remove
### uninstall

Remove previously installed packages using the `remove` command:
Remove previously installed packages using the `uninstall` command:

```shell
ape pm remove OpenZeppelin
ape pm uninstall OpenZeppelin
```

If there is a single version installed, the command will remove the single version.
If multiple versions are installed, pass additional arguments specifying the version(s) to be removed:

```shell
ape pm remove OpenZeppelin 4.5.0 4.6.0
ape pm uninstall OpenZeppelin 4.5.0 4.6.0
```

To skip the confirmation prompts, use the `--yes` flag (abbreviated as `-y`):

```shell
ape pm remove OpenZeppelin all --yes
ape pm uninstall OpenZeppelin all --yes
```

**NOTE**: Additionally, use the `all` special version key to delete all versions.
Expand Down Expand Up @@ -235,6 +235,12 @@ dependencies:
evm_version: paris
```

You can also specify `--config-override` in the `ape pm install` command to try different settings more adhoc:

```shell
ape pm install --config-override '{"solidity": {"evm_version": "paris"}}'
```

### Solidity Remappings

A common use-case for dependencies involves the Solidity plugin.
Expand Down Expand Up @@ -266,7 +272,8 @@ You can achieve this using the project manager:
from ape import accounts, project
# NOTE: This will compile the dependency
dependency_contract = project.dependencies["my_dependency"]["1.0.0"].DependencyContractType
dependency = project.dependencies["my_dependency"]["1.0.0"]
dependency_contract = dependency.project.DependencyContractType
my_account = accounts.load("alias")
deployed_contract = my_account.deploy(dependency_contract, "argument")
print(deployed_contract.address)
Expand Down
72 changes: 32 additions & 40 deletions docs/userguides/projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,64 +17,56 @@ project # The root project directory
Notice that you can configure you ape project using the `ape-config.yaml` file.
See the [configuration guide](./config.html) for a more detailed explanation of settings you can adjust.

## Adding Plugins
## The Local Project

Your project may require plugins.
To install plugins, use the `ape plugins install .` command.
Learn more about configuring your project's required plugins by following [this guide](./installing_plugins.html).

## Compiling Contracts

The project manager object is a representation of your current project.
Access it from the root `ape` namespace:
After you have a local project and you are in the directory of that project, the global `project` reference in Ape will refer to this project.
You can see this by typing `project` in the `ape console`:

```python
from ape import project
```

Your `project` contains all the "relevant" files, such as source files in the `contracts/` directory.
Use the following command to compile all contracts in the `contracts/` directory:

```bash
ape compile
In [1]: project
Out[1]: <ProjectManager ~/ApeProjects/ape-demo-project>
```

For more information on compiling your project, see [this guide](./compile.html).
In this case, my terminal's current working directory is the same as a local project named `ape-demo-project`.

## Deploying Contracts
## Other Projects

After compiling, the contract containers are accessible from the `project` manager.
Deploy them in the `console` or in scripts; for example:
You can reference other local projects on your computer by using the `Project` factory class (notice the capital `P`):

```python
from ape import accounts, project
from ape import Project

account = accounts.load("my_account_alias")
account.deploy(project.MyContract)
my_other_project = Project("../path/to/my/other/project")
_ = my_other_project.MyContract # Do anything you can do to the root-level project.
```

**NOTE**: You can also deploy contracts from the container itself:
## Project Manifests

Ape stores and caches artifacts in an [EthPM package manifest](https://eips.ethereum.org/EIPS/eip-2678).
When working with local projects, the manifests get placed in the `<project-path>/.build/__local__.json`.
However, you may obtain a manifest from a different location.
If that is the case, you can create a project directly from the manifest itself:

```python
from ape import accounts, project
from ape import Project

account = accounts.load("my_account_alias")
project.MyContract.deploy(sender=account)
# Pass in a manifest (object or dictionary), or a path to a manifest's JSON file.
project = Project.from_manifest("path/to/manifest.json")
_ = project.MyContract # Do anything you can do to the root-level project.
```

### Dependencies

To set up and use dependencies in your project, follow [this guide](./dependencies.html).
## Dependencies

## Scripts
Use other projects as dependencies in Ape.
There is an extensive guide you can read on this [here](./dependencies.html).
But it is important to note that the dependency system largely is dependent on the project system.
Dependencies are just projects after all; projects containing source files you both use in your projects or compile independently.

The scripts folder contains project automation scripts, such as deploy scripts, as well as other executable jobs, such as scripts for running simulations.
To learn more about scripting in Ape, see [the scripting guide](./scripts.html).
For example, access a dependency project and treat it like any other project this way:

## Testing
```python
from ape import project

Use tests to verify your project.
You can test your project using the `ape test` command.
The `ape test` command comes with the core-plugin `ape-test`.
The `ape-test` plugin extends the popular python testing framework [pytest](https://docs.pytest.org/en/6.2.x/contents.html).
Testing is a complex topic; learn more about testing using Ape framework [here](./testing.html).
dependency = project.dependencies.get_dependency("my-dependency", "1.0.0")
contract_type = dependency.project.ContractFromDependency
```
6 changes: 3 additions & 3 deletions docs/userguides/publishing.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Once your project has successfully compiled, you will have the start of your `Pa

## Tracking Deployments

If your project contains deployments that you wish to include in its package manifest, use the [track_deployment()](../methoddocs/managers.html#ape.managers.project.manager.ProjectManager.track_deployment) method.
If your project contains deployments that you wish to include in its package manifest, use the [project.deployments.track](../methoddocs/managers.html#ape.managers.project.manager.DeploymentManager.track) method.
Example:

```python
Expand All @@ -26,7 +26,7 @@ account = accounts.load("mainnet-account")

# Assume your project has a contract named 'MyContract' with constructor that accepts argument '123'.
contract = project.MyContract.deploy(123, sender=account)
project.track_deployment(contract)
project.deployments.track(contract)
```

If the contract is already deployed, you can use [Contract](../methoddocs/ape.html#ape.Contract) to get a contract instance:
Expand All @@ -35,7 +35,7 @@ If the contract is already deployed, you can use [Contract](../methoddocs/ape.ht
from ape import Contract, project

contract = Contract("0x12c17f958d2ee523a2206206994597c13d831e34")
project.track_deployment(contract)
project.deployments.track(contract)
```

For more information on accessing contract instances, follow [this guide](./contracts.html).
Expand Down
Loading

0 comments on commit 48cbf01

Please sign in to comment.