Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(contracts)!: StreamManager upgrades #112

Merged
merged 57 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
715a7f4
WIP
fubuloubu Sep 19, 2024
2117db1
refactor(sdk): check if non-zero factory
fubuloubu Sep 24, 2024
335eaa8
fix(contracts): forgot to update Validator.json interface
fubuloubu Sep 24, 2024
955b367
refactor: larger refactor of stream manager
fubuloubu Sep 25, 2024
a560e63
refactor(contracts): rename pricing example
fubuloubu Sep 25, 2024
2167491
refactor(py-sdk): remove unused exceptions
fubuloubu Sep 25, 2024
8513678
refactor(contracts): remove pricing example
fubuloubu Sep 25, 2024
7a7bd3c
fix(py-sdk): removed wrong exception
fubuloubu Sep 25, 2024
95a8a04
docs(test): add dev comments to token underflows
fubuloubu Sep 26, 2024
4620ddf
refactor(contracts,py-sdk)!: make create_stream use total stream amt
fubuloubu Sep 26, 2024
40e5f5a
refactor(contracts, py-sdk)!: change view function names, claim logic
fubuloubu Sep 26, 2024
ca8c85b
refactor(tests): updated test for contract/sdk changes, more modules
fubuloubu Sep 26, 2024
68c0212
test: add some extra checks
fubuloubu Sep 26, 2024
85b2b40
refactor(demo): upgrade demo script
fubuloubu Sep 26, 2024
c8d838b
docs: update the README
fubuloubu Sep 26, 2024
00c3d7e
refactor(py-sdk): better repr for Validator
fubuloubu Sep 26, 2024
11c499b
fix(scripts): deploy script was in wrong order for tokens/validators
fubuloubu Sep 26, 2024
f102bfc
feat(scripts): allow deploying test validator
fubuloubu Sep 26, 2024
47cd277
feat(py-sdk): display diff for `.set_validators`
fubuloubu Sep 26, 2024
36979e8
feat(py-sdk): allow replacing a validator
fubuloubu Sep 26, 2024
9bbd0e5
refactor(py-sdk): add typing and tests for replace_validator
fubuloubu Sep 27, 2024
080ef47
docs(contracts): add dev comment to two assertions
fubuloubu Sep 27, 2024
d6c76b8
docs(contracts): mis-capitalized
fubuloubu Sep 27, 2024
8627d93
refactor(py-sdk): consistency is key
fubuloubu Sep 27, 2024
cc12a80
refactor(contracts): reset new_controller; reorder a bit
fubuloubu Sep 27, 2024
2b03474
refactor(demo): wrong comments for time
fubuloubu Sep 27, 2024
eb9f34a
refactor(py-sdk): use floor div instead of int cast
fubuloubu Sep 27, 2024
7c25276
docs(contracts): add extensive NatSpec documentation to StreamManager
fubuloubu Sep 27, 2024
b8b07d0
refactor(py-sdk): don't use `args`
fubuloubu Sep 27, 2024
08f993b
style: fix `@return` not `@returns` in NatSpec
fubuloubu Sep 27, 2024
9674830
refactor(contracts,py-sdk,tests,scripts): Major refactor of stream math
fubuloubu Sep 28, 2024
e331306
style(scripts): remove unused imports
fubuloubu Sep 28, 2024
c933607
fix(contract): missing assertion for expiration in `add_funds`
fubuloubu Sep 28, 2024
5571eb3
feat(tests): add test for `add_funds`
fubuloubu Sep 28, 2024
e6a6f8d
refactor(contracts): make `StreamManager.cancel_stream` not do a claim
fubuloubu Sep 28, 2024
fb74988
feat(py-sdk): add helper methods for two timestamp info fields
fubuloubu Sep 28, 2024
18824b8
refactor(tests): remove unnecessary fixture
fubuloubu Sep 28, 2024
e17bb30
refactor(tests): move chain isolation to `stream` fixture
fubuloubu Sep 28, 2024
e37efdf
fix(tests): update `cancel_stream` test to make it work better
fubuloubu Sep 28, 2024
834e626
refactor(tests): remove unused fixture from test
fubuloubu Sep 28, 2024
d4f3c02
chore(config): add ignores for test reporting, display verbose cov
fubuloubu Sep 28, 2024
5d17c1b
refactor(contracts): update controller transfer events for better args
fubuloubu Sep 28, 2024
8cb68c9
refactor(contracts,py-sdk): update `id` -> `stream_id` in Stream events
fubuloubu Sep 28, 2024
dbdd779
refactor(contracts): update new/old arg names in owner transfer event
fubuloubu Sep 28, 2024
9262ad4
style(contracts): put event log emits last
fubuloubu Sep 28, 2024
cd9134c
refactor(contracts): add check of validator set uniqueness
fubuloubu Sep 28, 2024
c516102
docs(cotnracts): apply suggestions from code review
fubuloubu Sep 28, 2024
1f46007
docs(contracts): update `creator` -> `funder` in Validator interface
fubuloubu Sep 28, 2024
f3b133b
refactor(py-sdk): forgot to update event name
fubuloubu Oct 1, 2024
4c9ad42
fix(py-sdk): handle Taskiq dependencies
fubuloubu Oct 3, 2024
d20a794
fix(py-sdk): handle case when function is async
fubuloubu Oct 3, 2024
e6a2d1f
fix(py-sdk): ensure that UTC timestamps are returned
fubuloubu Oct 3, 2024
8084493
refactor(py-sdk): display validator set updates using info log
fubuloubu Oct 3, 2024
3d69bb9
refactor: apply suggestions from code review
fubuloubu Oct 3, 2024
b44eef7
refactor(contract): new_controller_proposed -> control_transfer_proposed
fubuloubu Oct 3, 2024
01b845c
fix(py-sdk): used timezone incorrectly
fubuloubu Oct 3, 2024
d989662
refactor(contracts): make memory var match event for clarity
fubuloubu Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,33 @@ Second, make sure to install the plugins:
$ ape plugins install . --upgrade
```

Next, prior to installing the SDK package, you have to compile the project:
Next, prior to installing the SDK package, you need to compile the project:

```sh
$ ape compile
```

```note
```{note}
The SDK package relies on a soft link in [`./sdk/py/apepay/manifest.json`](./sdk/py/apepay/manifest.json)
```

Lastly, install the SDK package via:

```sh
$ poetry install
$ pip install .
```

or for interactive installation do:

```sh
$ pip install -e .
```

Then you are ready to contribute!

### Setup (JS)

In order to contribute to the JS SDK and React component library, or to build the demo app, you need to first follow the [Python Setup instructions](#setup-python) to compile the smart contract package.
In order to contribute to the JS packages, you need to first follow the [Python Setup instructions](#setup-python) to compile the smart contract package.

Next, you need install the node packages for development:

Expand Down Expand Up @@ -108,7 +114,7 @@ To deploy a StreamManager (for testing purposes), run:

```sh
$ ape run deploy manager [TOKEN_ADDRESS [...]]
# Or if `ape tokens` is installed with a valid tokenlist
# Or if `ape tokens` is installed (with a valid tokenlist)
$ ape run deploy manager [TOKEN_SYMBOL [...]]
```

Expand All @@ -124,26 +130,30 @@ To deploy a Token (for testing use only), run:
$ ape run deploy token
```

```note
```{warning}
This test token has an unauthenticated mint, please do not use in production!
```

To run the demo ApePay cluster daemon, first run a node like `anvil`:

```sh
$ anvil --derivation-path "m/44'/60'/0'/" --block-time 1 --prune-history
$ anvil --block-time 1 --prune-history
```

**NOTE**: the `--derivation-path` flag makes ape's test accounts match anvil's

Then run the daemon:
Then run the example Silverback app:

```sh
$ silverback run scripts.daemon:app --network ::foundry --account TEST::0
$ silverback run bots.example:app
```

After that, it's suggested to start `ape console` and create a stream to watch the daemon react.

We also provide a simulation you can run instead using:

```sh
$ ape run demo
```

### Publishing

Given the monorepo structure, it's a bit more challenging to distribute all the packages in this repo.
Expand All @@ -154,23 +164,19 @@ TBD

#### Python SDK

To publish the Python package, there are 5 steps.
To publish the Python package, there are 4 steps.

```sh
# 1. Install everything
$ poetry install`
$ pip install .[dev]
# 2. Compile the package manifest
$ ape compile
# 3. Copy the package manifest to the Python SDK folder
$ cp .build/__local__.json sdk/py/apepay/manifest.json
# 4. Build the Python SDK with Poetry
$ poetry build
# 5. Publish the package
$ poetry publish
$ ape compile -f
# 3. Build the Python SDK with twine
$ twine build
# 4. Publish the package
$ twine publish
```

**NOTE**: make sure to revision the package before publishing, or it will fail.

#### JavaScript SDK and React component library

To publish the JS SDK, do the following:
Expand Down
18 changes: 6 additions & 12 deletions bots/example.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import os
from collections import defaultdict

from ape.types import AddressType
from silverback import SilverbackApp

from apepay import Stream, StreamManager
Expand All @@ -12,37 +10,33 @@

# NOTE: You would probably want to index your db by network and deployment address,
# if you were operating on multiple networks and/or deployments (for easy lookup)
db: defaultdict[AddressType, list[Stream]] = defaultdict(list)
db: dict[int, Stream] = dict()
# TODO: Migrate to `app.state.db` when feature becomes available


@app.on_startup()
async def load_db(_):
for stream in sm.active_streams():
while len(db[stream.creator]) < stream.stream_id:
db[stream.creator].append(None) # Fill with empty values
assert stream.stream_id == len(db[stream.creator])
db[stream.creator].append(stream)
db[stream.id] = stream


@sm.on_stream_created(app)
async def grant_product(stream):
assert stream.stream_id == len(db[stream.creator])
db[stream.creator].append(stream)
print(f"provisioning product for {stream.creator}")
db[stream.id] = stream
print(f"provisioning products: {stream.products}")
return stream.time_left


@sm.on_stream_funded(app)
async def update_product_funding(stream):
# NOTE: properties of stream have changed, you may not need to handle this, but typically you
# would want to update `stream.time_left` in db for use in user Stream life notifications
db[stream.creator][stream.stream_id] = stream
db[stream.id] = stream
return stream.time_left


@sm.on_stream_cancelled(app)
async def revoke_product(stream):
print(f"unprovisioning product for {stream.creator}")
db[stream.creator][stream.stream_id] = None
db[stream.id] = None
return stream.time_left
21 changes: 16 additions & 5 deletions contracts/StreamFactory.vy
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,35 @@ BLUEPRINT: public(immutable(address))
deployments: public(HashMap[address, address])


event ManagerCreated:
owner: indexed(address)
manager: address
accepted_tokens: DynArray[address, 20]
fubuloubu marked this conversation as resolved.
Show resolved Hide resolved
validators: DynArray[address, 10]


@deploy
def __init__(blueprint: address):
BLUEPRINT = blueprint


@external
def create(validators: DynArray[address, 10], accepted_tokens: DynArray[address, 20]) -> address:
#assert self.deployments[msg.sender] == empty(address) # dev: only one deployment allowed

deployment: address = create_from_blueprint(
def create(
accepted_tokens: DynArray[address, 20] = [],
validators: DynArray[address, 10] = [],
min_stream_time: uint256 = ONE_HOUR,
) -> address:
deployment: address = create_from_blueprint( # dev: only one deployment allowed
BLUEPRINT,
msg.sender, # Only caller can create
ONE_HOUR, # Safety parameter (not configurable)
min_stream_time, # Safety parameter for new streams
validators,
accepted_tokens, # whatever caller wants to accept
salt=convert(msg.sender, bytes32), # Ensures unique deployment per caller
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: I know it isn't being changed here, but out of curiosity, why limit one stream manager per sender?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

originally I was thinking that it would make sense to keep it like that and have per-product validators, but I think what I am gonna do is add a secondary String[32] "product" variable that also gets concatenated to the salt (and to the deployments mapping)

this way, in the StreamFactory Python SDK class I can actually loop through all of the known deployments of the factory (which I want to use the release version identifier as the create2 salt so you can get release by address) and look for the deployments that a particular user has made for a particular product name

code_offset=3,
)
self.deployments[msg.sender] = deployment

log ManagerCreated(msg.sender, deployment, accepted_tokens, validators)
fubuloubu marked this conversation as resolved.
Show resolved Hide resolved

return deployment
Loading
Loading