> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shinami.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gas Station API

> Increase user engagement and retention by sponsoring transactions

## Overview

You'll find API endpoints and key usage notes below. If you ever need help you can [reach out to us](/help-center/overview#contacting-support).

### Use Cases

Shinami's Gas Station API lets you easily sponsor transactions for your users. SUI is pulled from a fund you create to power these transactions, managed in Shinami's dashboard (see a how to create a fund on the [Sui Gas Station FAQ page of our Help Center](/help-center/sui/gas-station-faq)).

Shinami facilitates sponsored transactions based on logic determined by you, the app developer. Examples include sponsoring each user's initial transaction(s) for better onboarding and sponsoring transactions of a particular type that you want to encourage.

Apps looking to onboard and retain Web2 users may choose to sponsor all transactions and use Gas Station alongside Shinami's app-controlled [Invisible Wallets](/api-docs/sui/wallet-services/invisible-wallet-api) or user-controlled [zkLogin wallets](/api-docs/sui/wallet-services/zklogin-wallet-api) to make Web3 fully unseen. For a game, this allows players to focus on gameplay, while behind the scenes the game creates and modifies game assets in a Sui wallet designated for the player. Players get the benefits of Web3 without friction.

### Authentication, Rate Limits, and Error Handling

**Authentication**

You authenticate via an access key passed in a header ('X-Api-Key: ACCESS\_KEY') or in the request url, e.g. `https://api.us1.shinami.com/sui/gas/v1/ACCESS_KEY`. We recommend using a request header and not putting access keys in your request URLs for reduced visibility (in logs, etc).
For more information, including how to set up API access keys, see our [Authentication and API Keys](/developer-guides/core-integration-topics/authentication-and-api-keys) guide.

<Warning>
  **Call Shinami's Gas Station from your backend server**

  Shinami Gas Station does not support CORS requests, so you will get a CORS error if you make requests from your frontend. Use your backend server to integrate with Shinami's Gas Station. This limits exposure of your sponsorship access keys. If these keys are leaked, bad actors have the ability to sponsor transactions from your fund until it has been drained or you disable the key in our dashboard.

  For an example flow of combining frontend signing and/or transaction inputs with backend sponsorship, see our [Frontend signing + backend sponsorship](/developer-guides/sui/tutorials/gas-station-with-frontend-signing) tutorial.
</Warning>

**Rate Limits**

When you surpass the QPS limit for a key, we return a JSON-RPC error code `-32010`. We recommend implementing retries with a backoff to handle any rate limits errors that arise. You can also consider batching multiple Move calls into a single programmable transaction block for sponsorship. They'll execute in sequence, having the same effect as if they were submitted separately. Finally, you can [adjust the rate limits of your keys](/developer-guides/core-integration-topics/authentication-and-api-keys#update-a-key%E2%80%99s-qps%2Fcups-values) to better balance your QPS allotment across your keys.

**Error Handling**

See our Error Reference for guidance on the errors you may receive from our services, including a section on errors specific to the [Gas Station API](/developer-guides/core-integration-topics/error-reference#sui-gas-station-api).

### Send your first request

For a quick sample request that doesn't require building a transaction, ask for the balance of the fund your access key is tied to with [gas\_getFund](/api-docs/sui/gas-station/api#gas-getfund).

### Tutorials with E2E sample code

Check out our [TypeScript tutorial](/developer-guides/sui/tutorials/gas-station-backend-only) for more code samples and details on the end-to-end flow of creating, sponsoring, and executing a transaction. Also, since our Gas Station does not support CORS (browser) requests for security reasons, our [Frontend signing + backend sponsorship tutorial](/developer-guides/sui/tutorials/gas-station-with-frontend-signing) .

## Methods

### gas\_sponsorTransactionBlock

Sponsor a gas-less transaction. This request takes two parts of a `TransactionData` object: the sender address and the programmable transaction block to be executed (with gas information is omitted, this is considered a `TransactionKind`object). It asks the Gas Station to attach a gas object to it and produce a complete `TransactionData` object signed by the sponsor (your Gas Station fund). The returned `TransactionData` then needs to be signed by the sender and sent to Shinami's Node Service (or any full node) with both signatures to be executed with [`sui_executeTransactionBlock`](/api-docs/sui/node-service/json-rpc#sui-executetransactionblock).

**Important notes**

1. **You cannot use the gas object in a sponsored transaction for other purposes.** For example, you cannot write `const [coin] = txb.splitCoins(txb.gas,[txb.pure(100)]);` because it's accessing `txb.gas`. If you try to sponsor a TransactionKind that uses the gas object you will [get a JSON-RPC `-32602` error](/developer-guides/core-integration-topics/error-reference#sui-gas-station-api) .
2. **Gas Station doesn't support CORS, so you must send requests from your backend.** For more info and some sample code, see our [FE signing + BE sponsorship guide](/developer-guides/sui/tutorials/gas-station-with-frontend-signing).
3. **We charge a small fee (in SUI) per sponsorship** request to cover our costs. For details, visit the "Sui Gas Station" tab on the [Billing page](https://app.shinami.com/billing/#sui_gas) of your Shinami dashboard.
4. **You need to create a Gas Station fund in your Shinami dashboard before you create an access key.** When you create a gas station key, you assign it to a network (e.g. Testnet) and a fund on that network. For how to do that and find the deposit address, see our [Sui Gas Station Help Center page](/help-center/sui/gas-station-faq).
5. **Auto vs manual budgeting:** when you omit the `gasBudget` parameter, we set your gas budget automatically for you. We recommend this for most use cases. We put your `transactionBytes` through a [sui\_dryRunTransactionBlock](/api-docs/sui/node-service/json-rpc/write-api#sui-dryruntransactionblock) request as a free service before we attempt to sponsor it. This call will generate error messages for certain invalid transactions, and we'll return these errors back to you, which should be the same as if you had made a `sui_dryRunTransactionBlock` request yourself. For more on auto vs manual budgeting, see the [Appendix of our Gas Station tutorial](/developer-guides/sui/tutorials/gas-station-backend-only#tips-for-setting-your-sponsorship-budget).

**Request Parameters: Shinami SDK**

| Name         | Type               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| :----------- | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| tx           | GaslessTransaction | Shinami `GaslessTransaction` interface with the following members (For a code example of building and sponsoring a transaction, [see the Appendix](/api-docs/sui/gas-station/api#how-to-build-sponsor-sign-and-execute-a-transaction)):                                                                                                                                                                                                                                                                              |
| tx.txKind    | string             | Base64 encoded, BCS serialized `TransactionKind`                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| tx.sender    | string             | Sui address of the `TransactionKind` sender                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| tx.gasBudget | string \| number   | (Optional) The gas budget you wish to use for the transaction, in MIST. The transaction will fail if the gas cost exceeds this value. <br /> <br />  - If provided, we use the value as the budget of the sponsorship. <br /> <br /> - If omitted, we estimate the transaction cost for you. We then add a buffer (5% for non-shared objects, 25% for shared objects) and use that total value as the budget of the sponsorship.                                                                                     |
| tx.gasPrice  | string \| number   | (Optional) Gas price override. Must be equal to or greater than the current reference gas price. If omitted the current reference price is used. <br /> <br /> Under normal network conditions, the expectation is that this does not need to be set. For times of high network congestion, setting a gasPrice higher than the reference gas price gives your transaction higher priority. For more info, see [Sui's documentation on gas pricing](https://docs.sui.io/concepts/tokenomics/gas-pricing#computation). |

**Request Parameters: cURL**

| Name             | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| :--------------- | :----- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| transactionBytes | string | Base64 encoded, BCS serialized `TransactionKind`                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| sender           | string | Sui address of the `TransactionKind` sender                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| gasBudget        | string | (Optional) The gas budget you wish to use for the transaction, in MIST. The transaction will fail if the gas cost exceeds this value. <br /> <br />  - If provided, we use the value as the budget of the sponsorship. <br /> <br /> - If omitted, we estimate the transaction cost for you. We then add a buffer (5% for non-shared objects, 25% for shared objects) and use that total value as the budget of the sponsorship.                                                                           |
| gasPrice         | string | Optional gas price (must be equal to or greater than the current reference gas price). If omitted the current reference price is used. <br /> <br /> Under normal network conditions, the expectation is that this does not need to be set. For times of high network congestion, setting a gasPrice higher than the reference gas price gives your transaction higher priority. For more info, see [Sui's documentation on gas pricing](https://docs.sui.io/concepts/tokenomics/gas-pricing#computation). |

**Example Request Template**

The TypeScript example uses the [Shinami Clients SDK](https://www.npmjs.com/package/@shinami/clients), which you can install with:

<CodeGroup>
  ```bash Shell theme={null}
  npm install @shinami/clients
  ```
</CodeGroup>

Replace all instances of `{{name}}` with the actual value for that name.

<CodeGroup>
  ```bash cURL theme={null}
    curl https://api.us1.shinami.com/sui/gas/v1 \
    -X POST \
    -H 'X-API-Key: {{gasAccessKey}}' \
    -H 'Content-Type: application/json' \
    -d '{
            "jsonrpc":"2.0",
            "method":"gas_sponsorTransactionBlock",
            "params":[
                "{{gaslessTransactionBytes}}",
                "{{senderAddress}}",
                "{{gasBudget}}",
                "{{gasPrice}}"
            ],
            "id":1
        }'
  ```

  ```bash Shinami TypeScript SDK theme={null}
  import { GasStationClient } from "@shinami/clients/sui";

  const gasClient = new GasStationClient("{{gasAccessKey}}");

  const sponsorshipData = await gasClient.sponsorTransaction(
      {{tx}} // if tx.gasBudget is omitted we use our auto-budgeting feature
  ```
</CodeGroup>

**Example Response**

<CodeGroup>
  ```bash cURL theme={null}
  {
      "jsonrpc":"2.0",
      "result" :{
          "txBytes":"AAAAAQBCe5tpWnBOY2pjc+wz7B0Heo1Zj5cSbCJY3KWF60tybgljb2luX2ZsaXAKY2xhaW1fZmVlcwAAL44vPwjxyww1jOTrS7w8XpXnnhmIeecTKvuXScM6uIIBBqTsJrGuzKqeva+7IsFRCsYB7a6LpS34G1SEzn6DwSCoMHQAAAAAACCt2aRuz44LdsjRwsOpaPls3E4N7zVyDIT8AYWkinZQKh1jLUb/cEkQM/78TmOY3OqklD3PYlErTVc3i1q3A7xe6AMAAAAAAABAS0wAAAAAAAA=",
          "txDigest":"HvtKY9RwuE7NC4gLauLFPY3h5qepEy8R7aZHnc4gJu6G",
          "signature":"AAXr9gCHncXfpJiIuQLd1IyPCz/gIGebCeIFMkqollVsGfxVsoU1unAqOiQyvt4Xa18j/WC8dAN1pvf5Wsfnrw65rDp1CB4nXagWW48gUU79IRg3kJf+6erjnVYdenXh+A==",
          "expireAtTime":1695267721
      },
      "id":1
  }
  ```

  ```bash Shinami TypeScript SDK theme={null}
  {
      "txBytes":"AAAAAQBCe5tpWnBOY2pjc+wz7B0Heo1Zj5cSbCJY3KWF60tybgljb2luX2ZsaXAKY2xhaW1fZmVlcwAAL44vPwjxyww1jOTrS7w8XpXnnhmIeecTKvuXScM6uIIBBqTsJrGuzKqeva+7IsFRCsYB7a6LpS34G1SEzn6DwSCoMHQAAAAAACCt2aRuz44LdsjRwsOpaPls3E4N7zVyDIT8AYWkinZQKh1jLUb/cEkQM/78TmOY3OqklD3PYlErTVc3i1q3A7xe6AMAAAAAAABAS0wAAAAAAAA=",
      "txDigest":"HvtKY9RwuE7NC4gLauLFPY3h5qepEy8R7aZHnc4gJu6G",
      "signature":"AAXr9gCHncXfpJiIuQLd1IyPCz/gIGebCeIFMkqollVsGfxVsoU1unAqOiQyvt4Xa18j/WC8dAN1pvf5Wsfnrw65rDp1CB4nXagWW48gUU79IRg3kJf+6erjnVYdenXh+A==",
      "expireAtTime":1695267721
  }
  ```
</CodeGroup>

**Response Fields**

| Name         | Type   | Description                                                                                                                                             |
| :----------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
| txBytes      | string | Base64 encoded, BCS serialized `TransactionData`, which now includes the gas sponsorship data.                                                          |
| txDigest     | string | Base 58 encoded transaction digest. Store this and use it to call `gas_getSponsoredTransactionBlockStatus` defined below if needed.                     |
| signature    | string | Base64 encoded transaction signature from the sponsor (your Gas Station fund wallet).                                                                   |
| expireAtTime | int    | Expiration time of the assigned gas object, in Unix epoch seconds. All sponsorships created with this method are set to expire one hour after creation. |

### gas\_getSponsoredTransactionBlockStatus

Check the status of a transaction you've sponsored to see if the gas object has been spent or not.

<Info>
  Note that for many use cases, you will not need to check the status of your sponsorships. This is because when you get a successful response from the [`gas_sponsorTransactionBlock`](/api-docs/sui/gas-station/api#gas-sponsortransactionblock) request, you will immediately obtain a sender signature and submit it to our Node Service for execution (and therefore you'll know the status).
</Info>

**Request Parameters**

| Name              | Type   | Description                                                                |
| :---------------- | :----- | :------------------------------------------------------------------------- |
| transactionDigest | String | Base58 encoded transaction digest (returned by gasSponsorTransactionBlock) |

**Example Request Template**

The TypeScript example uses the [Shinami Clients SDK](https://www.npmjs.com/package/@shinami/clients), which you can install with:

<CodeGroup>
  ```bash Shell theme={null}
  npm install @shinami/clients
  ```
</CodeGroup>

Replace all instances of `{{name}}` with the actual value for that name.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.us1.shinami.com/sui/gas/v1 \
  -X POST \
  -H 'X-API-Key: {{gasAccessKey}}' \
  -H 'Content-Type: application/json' \
  -d '{
          "jsonrpc":"2.0",
          "method":"gas_getSponsoredTransactionBlockStatus",
          "params":[
              "{{transactionDigest}}"
          ],
          "id":1
      }'
  ```

  ```bash Shinami TypeScript SDK theme={null}
  import { GasStationClient } from "@shinami/clients/sui";

  const gasClient = new GasStationClient("{{gasAccessKey}}");

  // pass the digest returned by gas_sponsorTransactionBlock
  const status = await gas.getSponsoredTransactionStatus({{transactionDigest}});
  ```
</CodeGroup>

**Example Response**

<CodeGroup>
  ```bash JSON theme={null}
  {
    	"jsonrpc":"2.0",
    	"result":"IN_FLIGHT",
    	"id":1
  }
  ```

  ```bash Shinami TypeScript SDK theme={null}
  "IN_FLIGHT"
  ```
</CodeGroup>

**Possible Result Values**

| Name         | Type   | Description                                                                                                                                                                                |
| :----------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "IN\_FLIGHT" | String | A gas object has been assigned and its `expireAtTime` has not been reached. A transaction execution attempt has not been made.                                                             |
| "INVALID"    | String | We did not find a gas object attached to the transaction that was sponsored by the fund this access key is tied to OR The gas object's `expireAtTime` was reached and it is still unspent. |
| "COMPLETE"   | String | A transaction execution attempt was made and the attached gas object was spent. This does not guarantee that the transaction was successfully executed.                                    |

### gas\_getFund

Get the balance for the Gas Station fund tied to the request's API access key. When you create a Gas Station access key, you [link it to exactly one Gas Station fund](/developer-guides/core-integration-topics/authentication-and-api-keys#sui-gas-station). So, when you make this request, we return the balance for the fund that's tied to the access key you use for the request. To check which fund a Gas Station access key is tied too, see the [Sui Gas Station FAQ page of our Help Center](/help-center/sui/gas-station-faq)

**Request Parameters**

none

**Example Request Template**

The TypeScript example uses the [Shinami Clients SDK](https://www.npmjs.com/package/@shinami/clients), which you can install with:

<CodeGroup>
  ```bash Shell theme={null}
  npm install @shinami/clients
  ```
</CodeGroup>

Replace all instances of `{{name}}` with the actual value for that name.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.us1.shinami.com/sui/gas/v1 \
  -X POST \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
          "jsonrpc":"2.0",
          "method":"gas_getFund",
          "params":[],
          "id":1
      }'
  ```

  ```TypeScript Shinami TypeScript SDK theme={null}

  import { GasStationClient } from "@shinami/clients/sui";

  const gasClient = new GasStationClient("YOUR_API_KEY");

  const fundInfo = await gasClient.getFund();
  ```
</CodeGroup>

**Example Response**

<CodeGroup>
  ```bash JSON theme={null}
  {
      "id" : 1,
      "jsonrpc" : "2.0",
      "result" : {
          "balance" : 4915573880,
          "depositAddress" : "0x73e9b9188e84fc642290cf84c5b774f78bb49b60327f8fba23ebc4c5cfaf028b",
          "inFlight" : 0,
          "name" : "First test fund",
          "network" : "SUI_TESTNET"
     }
  }
  ```

  ```TypeScript Shinami TypeScript SDK theme={null}
  {
    network: 'SUI_TESTNET',
    name: 'First test fund',
    balance: 4915573880,
    inFlight: 0,
    depositAddress: '0x73e9b9188e84fc642290cf84c5b774f78bb49b60327f8fba23ebc4c5cfaf028b'
  }
  ```
</CodeGroup>

**Response Fields**

| Name           | Type           | Description                                                                                                                                                                                                                                                                                                                                 |
| :------------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| network        | String         | The network the fund is tied to.                                                                                                                                                                                                                                                                                                            |
| name           | String         | The name given to the fund when it was created.                                                                                                                                                                                                                                                                                             |
| balance        | Int            | The balance of the fund, in MIST. (1,000,000,000 MIST = 1 SUI)                                                                                                                                                                                                                                                                              |
| inFlight       | Int            | The amount we are currently withholding from your fund for active sponsorships, in MIST. This is what will be used to pay Sui transaction fees and Shinami fees for the sponsorship.                                                                                                                                                        |
| depositAddress | String \| null | `String` representing a Sui address if a deposit address has been created for the fund. `null` if no deposit address has been created. If you do not have a deposit address, follow the steps in the [Sui Gas Station FAQ page of our Help Center](/help-center/sui/gas-station-faq) and a deposit address will be automatically generated. |

## Appendix

### How to build, sponsor, sign, and execute a transaction

This section shows an example of how to build, sponsor, sign, and submit a transaction using the [Shinami Clients SDK](https://www.npmjs.com/package/@shinami/clients) and the [Mysten TypeScript SDK](https://www.npmjs.com/package/@mysten/sui). For a high-level image of the sponsorship flow [see here](/product-overviews/sui/gas-station#diagram). For multiple end-to-end examples, see our [Gas Station TypeScript tutorial](/developer-guides/sui/tutorials/gas-station-backend-only).

**Key requirements**

1. When you prepare a transaction for sponsorship, make you prepare a `TransactionKind`, which is a transaction without the gas information (since this will be assigned by our Gas Station). When you make the `build()` call on your `Transaction`, make sure that `onlyTransactionKind: true`. In the code below, our SDK's `buildGaslessTransaction` function does this [behind the scenes](https://github.com/shinamicorp/shinami-typescript-sdk/blob/main/packages/clients/src/sui/gas.ts#L189).

Replace all instances of `{{name}}` with the actual value for that name.

<CodeGroup>
  ```TypeScript Shinami TypeScript SDK expandable theme={null}
  // 1. Import everything you need
  import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
  import { fromB64 } from "@mysten/sui/utils";
  import { SuiClient, getFullnodeUrl } from "@mysten/sui/client";
  import { GasStationClient, buildGaslessTransaction } from "@shinami/clients/sui";

  // 2. Copy your Testnet Gas Station key value
  const GAS_STATION_ACCESS_KEY = "KEY_VALUE";

  // 3. Set up your Gas Station and Node Service clients. Here we're using the Mysten 
  //     free Node Service, which is useful for testing but not production.
  const nodeClient = new SuiClient({ url: getFullnodeUrl("testnet") });
  const gasStationClient = new GasStationClient(GAS_STATION_ACCESS_KEY);

  // 4. Generate a sender. In production, you won't be using a newly generated sender
  //  each time. The sender will often be a wallet the user connected or an embedded
  //  wallet you control for the user. This just makes for a shorter example.
  const sender = new Ed25519Keypair();

  // 5. Build a GaslessTransaction
  const gaslessTx = await buildGaslessTransaction(
    (txb) => {
        txb.moveCall({
            target: "0xfa0e78030bd16672174c2d6cc4cd5d1d1423d03c28a74909b2a148eda8bcca16::clock::access",
            arguments: [txb.object('0x6')],
        });
    },
    { sui: nodeClient }
  );

  // 6. Set the sender address and ask for a sponsorship
  gaslessTx.sender = sender.toSuiAddress();
  const { txBytes, signature: sponsorSignature } = await gasStationClient.sponsorTransaction(
    gaslessTx // by not setting gaslessTx.gasBudget we take
    //  advantage of Shinami auto-budgeting
  );

  // 7. Obtain the sender signature
  const { signature: senderSignature } = await sender.signTransaction(fromB64(txBytes));

  // 8. Submit the transaction, along with the sender and sponsor signatures
  const executeResponse = await nodeClient.executeTransactionBlock({
    transactionBlock: txBytes,
    signature: [sponsorSignature, senderSignature]
  });

  console.log(executeResponse);
  ```
</CodeGroup>
