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

Docs improvements #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ Transaction fees on Solana are very inexpensive, but users still need SOL to pay

Octane provides an API that lets users pay for transactions with SPL token transfers instead of native SOL.

It leverages unique properties of Solana:
It leverages the unique properties of Solana:

1) Transaction can have multiple signers, one of whom is the transaction fee payer. There is no single "msg.sender".

2) Transaction can have multiple instructions interacting with different programs that are executed atomically. If one instruction fail, whole transactions fails.
2) Transaction can have multiple instructions interacting with different programs that are executed atomically. If one instruction fails, whole transactions fails.

3) Each instruction refers to accounts it touches as writable or readable. It allows to validate transactions before signing.

Expand Down Expand Up @@ -52,7 +52,7 @@ You can get started by following the steps in [SETUP](SETUP.md). You'll need to

### Using Octane from a client app

If you already have set up an Octane node, or you are using a public endpoint from someone else, it's the time to integrate the node with your client code. Follow [this guide](docs/example-integration.md) to run your first transaction through Octane. You can also view all Octane endpoints and their parameters on [this page](docs/endpoints.md).
If you already have set up an Octane node, or you are using a public endpoint from someone else, it's time to integrate the node with your client code. Follow [this guide](docs/example-integration.md) to run your first transaction through Octane. You can also view all Octane endpoints and their parameters on [this page](docs/endpoints.md).

### Integrate it as a Node.js library

Expand Down Expand Up @@ -84,7 +84,7 @@ Learn more about these use cases in [Recipes](docs/recipes.md).

Octane operates trustlessly and is designed to be easily run by anyone in an adversarial environment.

It uses ratelimiting, transaction validation, and transaction simulation to mitigate DoS, spam, draining, and other attacks.
It uses rate limiting, transaction validation, and transaction simulation to mitigate DoS, spam, draining, and other attacks.

However, there are some risks associated with running an Octane node:

Expand All @@ -99,7 +99,7 @@ Follow these recommendations to minimize risks:
5. Regularly check that prices and liquidity of SPL tokens allow your profitably pay for transaction fees in SOL.
6. If your Octane node makes profit, regularly withdraw that profit to another keypair.
7. When using Octane as a library in your backend, make sure to:
1. Never return fee payer's signature of an unconfirmed transaction to a user. You must submit transaction to the network from the backend.
1. Never return the fee payer's signature of an unconfirmed transaction to a user. You must submit transaction to the network from the backend.
2. Implement duplicated transaction checks, limits per user and general rate limits.

## Contributing
Expand Down
10 changes: 5 additions & 5 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Generates JSON to put in `config.json` as token fees for a specific endpoint. It

Config should be generated for each endpoint separately — in most cases, with different arguments.

Endpoints like `transfer` and `buildWhirlpoolSwap` require less SOL, so margins could be higher. Endpoint `createAssociatedTokenAccount`, that charges fee payer for a rent exemption payment on a new token account, must include `--include-account-fees` and may use lower margins, since the original price would be much higher.
Endpoints like `transfer` and `buildWhirlpoolSwap` require less SOL, so margins could be higher. Endpoint `createAssociatedTokenAccount`, which charges fee payer for a rent exemption payment on a new token account, must include `--include-account-fees` and may use lower margins, since the original price would be much higher.

```
{
Expand Down Expand Up @@ -42,8 +42,8 @@ Endpoints like `transfer` and `buildWhirlpoolSwap` require less SOL, so margins
| Argument | Description | Default value |
|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| -t, --tokens-from-top <number> | Tokens from the top of Jupiter aggregator to include | 10 |
| -m, --margin <number> | Part of total user-paid fee that fee payers take as a surplus to transaction costs. From 0 to 1. For example, 0.5 would mean that user pays 2x the SOL signature fee. | 0.9 |
| -a, --include-account-fees | Includes cost creating an associated token account in each fee pre-margin. Use this flag when filling out the endpoints.createAssociatedAccount part of config. | |
| -m, --margin <number> | Part of the total user-paid fee that fee payers take as a surplus to transaction costs. From 0 to 1. For example, 0.5 would mean that the user pays 2x the SOL signature fee. | 0.9 |
| -a, --include-account-fees | Includes the cost of creating an associated token account in each fee pre-margin. Use this flag when filling out the endpoints.createAssociatedAccount part of config. | |

## Generating a config entry

Expand All @@ -53,8 +53,8 @@ Generates a config entry for a single provided token. All rules of `generate-con

| Argument | Description | Default value |
|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| -m, --margin <number> | Part of total user-paid fee that fee payers take as a surplus to transaction costs. From 0 to 1. For example, 0.5 would mean that user pays 2x the SOL signature fee. | 0.9 |
| -a, --include-account-fees | Includes cost creating an associated token account in each fee pre-margin. Use this flag when filling out the endpoints.createAssociatedAccount part of config. | |
| -m, --margin <number> | Part of the total user-paid fee that fee payers take as a surplus to transaction costs. From 0 to 1. For example, 0.5 would mean that user pays 2x the SOL signature fee. | 0.9 |
| -a, --include-account-fees | Includes the cost of creating an associated token account in each fee pre-margin. Use this flag when filling out the endpoints.createAssociatedAccount part of config. | |


## Swapping tokens
Expand Down
4 changes: 2 additions & 2 deletions docs/endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

`GET /api/`

Load Octane node configuration. Config is used to correctly set token fee and fee payer in the created transaction.
Load Octane node configuration. Config is used to correctly set the token fee and fee payer in the created transaction.

No parameters.

Expand Down Expand Up @@ -58,7 +58,7 @@ Example response:

`POST /api/createAssociatedTokenAccount`

The transaction should transfer a fee to Octane as first instruction and create new associated token account as second instruction.
The transaction should transfer a fee to Octane as the first instruction and create a new associated token account as the second instruction.

| Parameter | Type | Description |
|-------------|--------|-------------------------------------------------------------|
Expand Down
10 changes: 5 additions & 5 deletions docs/example-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const simpleTransactionFee = response.endpoints.transfer.tokens[0].fee;

Before we can proceed, we'll need some additional information about the user:
```javascript
// `publicKey` should be loaded from wallet adapter
// `publicKey` should be loaded from the wallet adapter
const userTokenAccount = await getAssociatedTokenAddress(mint, publicKey);

// Let's say we want to send a gasless transfer to this public key
Expand All @@ -31,8 +31,8 @@ const targetAccount = await getAssociatedTokenAddress(mint, targetOwner);

Now, we're ready to create the transaction with two instructions:

1. Send token fee to Octane's account
2. Send token transfer to any public key (but this transaction could be anything else)
1. Send the token fee to Octane's account
2. Send the token transfer to any public key (but this transaction could be anything else)

We also should set feePayer and recentBlockhash, and then sign the transaction using the end user wallet.

Expand All @@ -49,9 +49,9 @@ await signTransaction(transaction);

## Submit transaction

Now, we have the transaction with end user's signature. However, the transaction lacks signature of fee payer.
Now, we have the transaction with end user's signature. However, the transaction lacks the signature of fee payer.

We need to call an Octane HTTP endpoint to get transaction signed and submitted to the network:
We need to call an Octane HTTP endpoint to get the transaction signed and submitted to the network:

```javascript
const octaneResponse = (await axios.post('https://octane-mainnet-beta.breakroom.show/api/transfer', {
Expand Down
12 changes: 6 additions & 6 deletions docs/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ You can call them from your backend endpoints when your use case fits in the Oct

#### signWithTokenFee

Sign transaction by fee payer if the first instruction of transaction is a transfer of token fee and the rest instructions do not interact with fee payer's wallet.
Sign transaction by fee payer if the first instruction of transaction is a transfer of token fee and the rest of instructions do not interact with fee payer's wallet.

It also implements additional checks: duplicated transactions, fee payer source and failing transactions detection using simulation.

Expand Down Expand Up @@ -58,13 +58,13 @@ await sendAndConfirmRawTransaction(connection, transaction.serialize(), { commit
| lamportsPerSignature | number | Maximum transaction fee payment amount in lamports |
| allowedTokens | core.TokenFee[] from '@solana/octane-core' | List of tokens that can be used for Octane fees with associated info |
| cache | Cache from 'cache-manager' | A cache to store duplicate transactions |
| sameSourceTimeout | number | An interval for transactions with same token fee source, ms |
| sameSourceTimeout | number | An interval for transactions with the same token fee source, ms |

#### createAccountIfTokenFeePaid

Signs transaction by fee payer if both statements are true:

a) the first instruction is a transfer of token fee to given account
a) the first instruction is a transfer of token fee to a given account

b) the second instruction creates an associated token account with initialization fees paid by fee payer.

Expand Down Expand Up @@ -112,7 +112,7 @@ Creates a non-signed transaction with Whirlpools swap from one SPL token to unwr

The transaction has to be signed using `signGeneratedTransaction`. If you want full protection against failed transaction spend, you have to sign after receiving user's signature.

`messageToken` has to be passed to `signGeneratedTransaction` to verify that transaction hasn't changed since the generation.
`messageToken` has to be passed to `signGeneratedTransaction` to verify that the transaction hasn't changed since the generation.

Fee has to be paid in swapped token.

Expand Down Expand Up @@ -148,7 +148,7 @@ const { transaction, quote, messageToken } = await buildWhirlpoolsSwapToSOL(

#### signGeneratedTransaction

Signs previously generated transaction by Octane. The transaction should have user's signature. The authenticity check is provided using `messageToken` argument, which is a signature for transaction's message.
Signs previously generated transaction by Octane. The transaction should have the user's signature. The authenticity check is provided using `messageToken` argument, which is a signature for transaction's message.

```javascript
const { signature } = await signGeneratedTransaction(
Expand Down Expand Up @@ -240,7 +240,7 @@ try {

### Payer utils

When providing gasless transactions for your users, you manage a Solana wallet that accepts tokens and stores SOL for user's transactions. Naturally, amount of SOL decreases and balances of tokens increase. You have to regularly swap tokens for SOL to keep node operational. Additionally, node operators have to create associated token accounts for each token they receive and setup pricing settings for each token individually.
When providing gasless transactions for your users, you manage a Solana wallet that accepts tokens and stores SOL for user's transactions. Naturally, the amount of SOL decreases and the balances of tokens increase. You have to regularly swap tokens for SOL to keep node operational. Additionally, node operators have to create associated token accounts for each token they receive and setup pricing settings for each token individually.

`PayerUtils` are helper functions to manage your fee payer signing account.

Expand Down
8 changes: 4 additions & 4 deletions docs/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ If you are considering integrating with Octane, this page will provide examples

## Transaction fees in SPL tokens

In its simplest form, Octane allows to submit transactions in client-side code without paying transaction fees in SOL in exchange for an equivalent payment in liquid SPL tokens. For example, a client pays 0.001 USDC to Octane node and submits transaction with fee payer equal to Octane address.
In its simplest form, Octane allows to submit transactions in client-side code without paying transaction fees in SOL in exchange for an equivalent payment in liquid SPL tokens. For example, a client pays 0.001 USDC to Octane node and submits a transaction with a fee payer equal to the Octane address.

To do that, you need form a transaction in your client code (whether it's a mobile or web app) with token transfer to Octane as first instruction and any other instructions ("payload"). Then, you need to call Octane node's `/api/transfer` endpoint with serialized transaction. The endpoint will sign transaction on Octane's behalf and submit it to the network.
To do that, you need to form a transaction in your client code (whether it's a mobile or web app) with token transfer to Octane as first instruction and any other instructions ("payload"). Then, you need to call Octane node's `/api/transfer` endpoint with serialized transaction. The endpoint will sign transaction on Octane's behalf and submit it to the network.

Octane's configuration with fee payer public key and fee amount for your operations can be loaded by calling `/api` endpoint.

Expand Down Expand Up @@ -44,7 +44,7 @@ Also, you have to set checks on token emission using ReCaptcha, auth or whitelis

Octane generally doesn't support creating accounts in transaction instructions. However, there is a separate endpoint to create an associated token account for any owner and mint without spending SOL.

When implementing SPL token transfers, if transfer sender doesn't have SOL and transfer recipient doesn't have associated token account, use `/api/createAssociatedTokenAccount` Octane endpoint prior to sending the actual transfer transaction using `/api/transfer`.
When implementing SPL token transfers, if transfer sender doesn't have SOL and transfer recipient doesn't have an associated token account, use `/api/createAssociatedTokenAccount` Octane endpoint prior to sending the actual transfer transaction using `/api/transfer`.

This endpoint accepts a transaction with two instructions:
* First instruction should transfer a fee to Octane (this fee is higher than normal, since Octane pays for rent-exemption minimum)
Expand Down Expand Up @@ -124,4 +124,4 @@ _Examples:_
You shouldn't use Octane when you want to run transactions that do not require end user's signature. For example, token airdrops do not require recipient's signature. You can run them without Octane.


You shouldn't fully sponsor transactions for unauthorized users (or when authorization process is easy to automate) or without setting strict limits on amount of transactions.
You shouldn't fully sponsor transactions for unauthorized users (or when the authorization process is easy to automate) or without setting strict limits on amount of transactions.