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

aragonAPI docs restructure #127

Merged
merged 10 commits into from Apr 4, 2019
@@ -0,0 +1,40 @@
---
id: api-intro
title: aragonAPI Introduction
sidebar_label: Introduction
hide_title: true
---

![](/docs/assets/brand/aragonapi.png)

Standard set of APIs and specifications used to interact with aragonOS-powered contracts by handling transaction pathing, upgradeability, and contract state without depending of a centralized service.

## Reference implementations in specific languages

### JavaScript

A JavaScript implementation of aragonAPI, used to interact with aragonOS by handling transaction pathing, upgradeability, identity providers and state of the contracts.
This conversation was marked as resolved by 0xGabi

This comment has been minimized.

Copy link
@2color

2color Apr 3, 2019

Contributor
Suggested change
A JavaScript implementation of aragonAPI, used to interact with aragonOS by handling transaction pathing, upgradeability, identity providers and state of the contracts.
A JavaScript implementation of the aragonAPI, used to interact with aragonOS by handling transaction pathing, upgradeability, identity providers and state of the contracts.

Some of the things you can do with the JavaScript implementation are:

- Connect contracts to front-end
- Interact with the EVM and [aragonOS](os-intro.md) when using the full Aragon System
- Abstract Web3 so a direct Web3 connection isn't exposed to the browser
This conversation was marked as resolved by 0xGabi

This comment has been minimized.

Copy link
@2color

2color Apr 3, 2019

Contributor
Suggested change
- Abstract Web3 so a direct Web3 connection isn't exposed to the browser
- Interact with contracts directly – an abstraction over web3.js
- Use a store method wich mantains the application state using caching
This conversation was marked as resolved by 0xGabi

This comment has been minimized.

Copy link
@2color

2color Apr 3, 2019

Contributor
Suggested change
- Use a store method wich mantains the application state using caching
- Get access to application state with built in client-side caching
- Pull [Radspec](human-readable-txs.md) notices from contracts

This comment has been minimized.

Copy link
@sohkai

sohkai Apr 3, 2019

Member
Suggested change
- Pull [Radspec](human-readable-txs.md) notices from contracts
- Create human-readable transaction descriptions for your smart contracts through [Radspec](human-readable-txs.md)

#### Quick Start

- [Quick Start for apps](js-quick-start.md)

#### Docs

- [App API](js-ref-app.md)
- [Wrapper API](js-ref-wrapper.md)
- [React API](js-ref-react.md)
- [Providers](js-ref-providers.md)
- [Architecture of Aragon apps and their communication channels](js-ref-architecture.md)

#### Guides

- [Background Scripts](js-guide-bg-scripts.md)
@@ -24,7 +24,6 @@ The first label in the ENS name is the name of our app. This can be anything you

The second and third label is the name of the [aragonPM](package-management.md) (aragonPM) registry that your repository will be (or is) registered to. For the sake of simplicity, this guide assumes that you have rights to create repositories on aragonpm.eth, but you could deploy your own aragonPM registry if you so desire.


## Writing a simple contract

To illustrate how easy it is to use aragonOS, we will build our app as a vanilla smart contract, without any Aragon-specific interfaces at all.
@@ -57,7 +56,6 @@ contract CounterApp {

Pretty simple, right? You might wonder why we would bother adding events to this smart contract, but it comes in handy later for illustration purposes — and we can also create an activity feed from it, if we wanted to.


## 3 steps to governance and upgradeability

Now for the interesting part: making our simple smart contract an Aragon app.
@@ -107,13 +105,12 @@ contract CounterApp is AragonApp {

That's it. In 3 steps, you now have an Aragon app, with full upgradeability and modular governance.


## Descriptive transactions

Aragon wants to be as user friendly as possible, so it provides an easy way for developers to describe what their smart contracts do in a human readable way. It's called [Radspec](human-readable-txs.md). It works by putting `@notice` statements alongside a human readable description for the function.

```solidity
contract CounterApp is AragonApp {
contract CounterApp is AragonApp {
/**
* @notice Increment the counter by 1
*/
@@ -138,14 +135,13 @@ Apps are run inside an iframe, which means that it only has access to its own DO

Then the client takes care of connecting to Ethereum via Web3, and also handles things like signing transactions, displaying notifications and more to the end-user.

All of this is achieved by using aragonAPI. aragonAPI is split in two parts: one for clients and one for apps. The client portion of aragonAPI reads *requests* from the app over RPC, sandboxes apps and performs Web3 actions, whereas the app portion provides a simple API to communicate with the client (to read state, send transactions and more).
All of this is achieved by using aragonAPI. aragonAPI is split in two parts: one for clients and one for apps. The client portion of aragonAPI reads _requests_ from the app over RPC, sandboxes apps and performs Web3 actions, whereas the app portion provides a simple API to communicate with the client (to read state, send transactions and more).

Because we're building an app, all we need is `@aragon/client` and our template already has that installed.


### Background workers and building state

Apps usually want to listen to events using Web3 and build an application state from those events. This concept is also known as *event sourcing*.
Apps usually want to listen to events using Web3 and build an application state from those events. This concept is also known as _event sourcing_.

aragonAPI was built with event sourcing in mind. To build state continually without having the app loaded indefinitely, though, we need to run a background script.

@@ -161,7 +157,7 @@ import Aragon from '@aragon/client'
const app = new Aragon()
const initialState = {
count: 0
count: 0,
}
app.store(async (state, event) => {
if (state === null) state = initialState
@@ -205,17 +201,17 @@ Now let's write the view portion of our app. In our case, this is a simple HTML

```html
<!-- app/index.html !-->
<!doctype html>
<!DOCTYPE html>
<html>
<head>
<head>
<title>Counter App</title>
</head>
<body>
</head>
<body>
<button id="decrement">-</button>
<div id="view">...</div>
<button id="increment">+</button>
<script src="app.js"></script>
</body>
</body>
</html>
```

@@ -224,18 +220,16 @@ Now let's write the view portion of our app. In our case, this is a simple HTML
import Aragon, { providers } from '@aragon/client'
const initializeApp = () => {
const app = new Aragon(
new providers.WindowMessage(window.parent)
)
const app = new Aragon(new providers.WindowMessage(window.parent))
const view = document.getElementById('view')
app.state().subscribe(
(state) => {
state => {
// the state is null in the beginning, when there are no event emitted from the contract
view.innerHTML = `The counter is ${state ? state.count : 0}`
},
(err) => {
err => {
view.innerHTML = 'An error occured, check the console'
console.log(err)
}
@@ -263,19 +257,19 @@ That's it! Internally, `state` observes the `state` key in cache and emits every

### Sending transactions

Our users need to be able to increment and decrement the counter. For this, we publish what is called an *intent* to the wrapper.
Our users need to be able to increment and decrement the counter. For this, we publish what is called an _intent_ to the wrapper.

An intent is an action you would like to occur on a specific contract. This intent is handled by the client, which will calculate a *transaction path* using the ACL of our DAO.
An intent is an action you would like to occur on a specific contract. This intent is handled by the client, which will calculate a _transaction path_ using the ACL of our DAO.

To understand transaction paths, we must first understand a little bit about how the ACL works.

The [ACL (Access Control List)](acl-intro.md) is a simple mapping of *who* can perform *what* actions *where*. In our case, *someone* can perform an action guarded by a specific role (the *what*) on our app (the *where*).
The [ACL (Access Control List)](acl-intro.md) is a simple mapping of _who_ can perform _what_ actions _where_. In our case, _someone_ can perform an action guarded by a specific role (the _what_) on our app (the _where_).

However, it is entirely possible that users can not perform actions directly. For example, in order to increment the counter, we might want a decision making process, such as a vote. The beauty of aragonOS is that we never need to specify this directly, as this is handled by the ACL.

We simply say that the only one (*who*) that can perform increments and decrements (*what*) on our app (*where*) is the voting app. This is not done at compile time, it is done at run time.
We simply say that the only one (_who_) that can perform increments and decrements (_what_) on our app (_where_) is the voting app. This is not done at compile time, it is done at run time.

This works because of a concept called [*forwarders*](forwarding-intro.md). A forwarder is simply an app that can execute transactions on someone's behalf, if the ACL permits it, and that app can have its own *arbitrary conditions* under which it wants to execute your transaction! In the example of the voting app, the voting app will only execute your transaction if the vote passes.
This works because of a concept called [_forwarders_](forwarding-intro.md). A forwarder is simply an app that can execute transactions on someone's behalf, if the ACL permits it, and that app can have its own _arbitrary conditions_ under which it wants to execute your transaction! In the example of the voting app, the voting app will only execute your transaction if the vote passes.

It's really simple to use. Let's add our intents to our app:

@@ -298,7 +292,6 @@ const initializeApp = () => {

That's it! Now whenever the user clicks one of either the increment or decrement buttons, an intent is sent to the wrapper, and it will show the user a transaction to sign.


### The build script

Since we're importing Node.js modules in our front-end, we need a build script. For this, we opted to use `parcel` because it has zero config, but you can use your favorite bundler.
@@ -317,7 +310,6 @@ Let's add the build script to `package.json`:

You can now build the front-end of your app by running `npm run build`.


## Writing the manifest files

In order for aragonAPI to function, it needs some metadata about your app. This metadata is specified in two manifest files; `manifest.json` and `arapp.json`.
@@ -393,12 +385,10 @@ Let's add the scripts we need to `package.json`:

```json
{
"scripts": {
"start:app": "npm run build -- --no-minify && parcel serve app/index.html -p 8001 --out-dir dist/ --no-cache",
"start:aragon:http": "npx aragon run --http localhost:8001 --http-served-from ./dist"
}
}
```

@@ -415,7 +405,6 @@ Let's add the scripts we need to `package.json`:

Now that we're confident that our app will work and amaze the world, we should publish it. You can follow the publish guide to learn [how to publish in different environments](guides-publish.md).


### More CLI commands

You can check the [aragonCLI documentation](cli-main-commands.md) for an in-depth description of how all the commands available in the CLI work.
@@ -5,71 +5,74 @@
* LICENSE file in the root directory of this source tree.
*/

const React = require('react');
const React = require('react')
const { theme } = require('@aragon/ui')
const styled = require('styled-components').default

const FooterContainer = styled.footer`
`
const FooterContainer = styled.footer``

class Footer extends React.Component {
docUrl(doc, language) {
const baseUrl = this.props.config.baseUrl;
return baseUrl + 'docs/' + (language ? language + '/' : '') + doc + '.html';
const baseUrl = this.props.config.baseUrl
return baseUrl + 'docs/' + (language ? language + '/' : '') + doc + '.html'
}

pageUrl(doc, language) {
const baseUrl = this.props.config.baseUrl;
return baseUrl + (language ? language + '/' : '') + doc + '.html';
const baseUrl = this.props.config.baseUrl
return baseUrl + (language ? language + '/' : '') + doc + '.html'
}

render() {
const currentYear = new Date().getFullYear();
const currentYear = new Date().getFullYear()
return (
<FooterContainer className="nav-footer" id="footer">
<section className="sitemap">
<div>
<a href={this.props.config.baseUrl} className="nav-home">
<img
src={this.props.config.baseUrl + this.props.config.footerIcon}
alt={this.props.config.title}
width="66"
height="58"
/>
src={this.props.config.baseUrl + this.props.config.footerIcon}
alt={this.props.config.title}
width="66"
height="58"
/>
</a>
</div>
<div>
<h5>Documentation</h5>
<a href={this.docUrl('getting-started')}>Get started</a>
<a href={this.docUrl('tutorial')}>Tutorial</a>
<a href={this.docUrl('aragonos-intro')}>aragonOS</a>
<a href={this.docUrl('aragonjs-intro')}>aragonAPI</a>
<a href={this.docUrl('api-intro')}>aragonAPI</a>
<a href={this.docUrl('aragonui-intro')}>aragonUI</a>
</div>
<div>
<h5>Community</h5>
<a href="http://wiki.aragon.org/projects/" target="_blank">
User showcase
</a>
<a href="https://aragon.chat" target="_blank">Community chat</a>
<a href="https://aragon.chat" target="_blank">
Community chat
</a>
<a
href="https://twitter.com/AragonProject"
target="_blank"
rel="noreferrer noopener">
rel="noreferrer noopener"
>
Twitter
</a>
</div>
<div>
<h5>More</h5>
<a href="https://blog.aragon.org">Blog</a>
<a href="https://github.com/aragon">GitHub</a>
<a href="https://wiki.aragon.org/documentation/legal/Privacy_policy/">Privacy policy</a>
<a href="https://wiki.aragon.org/documentation/legal/Privacy_policy/">
Privacy policy
</a>
</div>
</section>
</FooterContainer>
);
)
}
}

module.exports = Footer;
module.exports = Footer
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.