From e72841c022bd4d8692aae17909b3962859718020 Mon Sep 17 00:00:00 2001 From: itsasecret <87604944+tudorpintea999@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:24:09 +0200 Subject: [PATCH 1/6] Update CLI.md --- docs/CLI.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/CLI.md b/docs/CLI.md index b1b29704..77f39215 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -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. ``` { @@ -42,8 +42,8 @@ Endpoints like `transfer` and `buildWhirlpoolSwap` require less SOL, so margins | Argument | Description | Default value | |--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| | -t, --tokens-from-top | Tokens from the top of Jupiter aggregator to include | 10 | -| -m, --margin | 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 | 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 @@ -53,8 +53,8 @@ Generates a config entry for a single provided token. All rules of `generate-con | Argument | Description | Default value | |--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| -| -m, --margin | 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 | 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 From 94557f7642cf2fef400867aaced6ed08a8c4f4a9 Mon Sep 17 00:00:00 2001 From: itsasecret <87604944+tudorpintea999@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:24:36 +0200 Subject: [PATCH 2/6] Update endpoints.md --- docs/endpoints.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/endpoints.md b/docs/endpoints.md index 97fad833..eccc04c1 100644 --- a/docs/endpoints.md +++ b/docs/endpoints.md @@ -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. @@ -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 | |-------------|--------|-------------------------------------------------------------| From 326e3f7cd8a03e998f6ceeb3ef31ae9c111c52ff Mon Sep 17 00:00:00 2001 From: itsasecret <87604944+tudorpintea999@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:28:19 +0200 Subject: [PATCH 3/6] Update example-integration.md --- docs/example-integration.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/example-integration.md b/docs/example-integration.md index c85445f0..c6c131ec 100644 --- a/docs/example-integration.md +++ b/docs/example-integration.md @@ -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 @@ -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. @@ -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', { From b9cd7ee7fc5be26ab4e81bd8635401f5f5a70d56 Mon Sep 17 00:00:00 2001 From: itsasecret <87604944+tudorpintea999@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:54:38 +0200 Subject: [PATCH 4/6] Update library.md --- docs/library.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/library.md b/docs/library.md index 248bd452..95f9e90d 100644 --- a/docs/library.md +++ b/docs/library.md @@ -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. @@ -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. @@ -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. @@ -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( @@ -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. From 8c7ad0fa6885dbae238360aab92c9b00a80aeb45 Mon Sep 17 00:00:00 2001 From: itsasecret <87604944+tudorpintea999@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:57:07 +0200 Subject: [PATCH 5/6] Update recipes.md --- docs/recipes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/recipes.md b/docs/recipes.md index 5d093de8..f8fa0362 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -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. @@ -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) @@ -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. From 1cec8967de9cd1f64b95339b4d225ecf3a1f5fdd Mon Sep 17 00:00:00 2001 From: itsasecret <87604944+tudorpintea999@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:59:09 +0200 Subject: [PATCH 6/6] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e6d52899..1920f472 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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 @@ -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: @@ -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