Overview
Shinami’s Invisible Wallets abstract away Web3 elements like seed phrases, third-party wallet connections, gas fees, and signing popups. They are embedded, backend wallets under the shared custody of your app and Shinami. Both parties must cooperate in order to obtain a valid signature. You’ll find API endpoints and key usage notes below. If you ever need help you can reach out to us.Use Cases
Core use cases include app-managed NFTs or closed-loop tokens. For a breakdown of the wallets we offer and wallet use-cases, see our high-level guide.Shinami Gas Station Integration
All methods below that write to the Aptos blockchain have their gas fees sponsored by you via a Gas Station fund you create. This is because Invisible Wallets are designed to easily onboard Web2-native users (who may not want to download a wallet app, manage a seed phrase, and complete KYC checks to buy APT for gas). See the Aptos Gas Station FAQ page in our Help Center for how guidance on how to set up a fund.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 (https://api.us1.shinami.com/aptos/wallet/v1/ACCESS_KEY
). We recommend using a request header and not putting access keys in your request URLs for reduced visibility (in logs, etc). These steps are done automatically by our TypeScript SDK. Region URLs - us1
above - only work with API keys created in the same region. So, to use this API, you’ll make Wallet Services API keys in our US East - us1
region.
See our Authentication and API Keys guide for how to set up a Wallet-Services-only access key and an access key with Wallet Services and Gas Station rights (needed to execute transactions and initialize Invisible Wallets on chain).
Call this API from your backendShinami Wallet Services do not support CORS requests, so if you make requests to these APIs from your frontend you’ll get a CORS error. This is for security reasons: exposed keys and wallet information could lead to malicious actors signing transactions on behalf of your users.
-32010
. We recommend implementing retries with a backoff to handle any rate limits errors that arise. You can also adjust the rate limits of your keys 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 Invisible Wallet API.
WalletId and Secret Pairing
When you create an Invisible Wallet, you must create, store, link, and never change the following two values:walletId
: Your internal id for a wallet. When you provide us awalletId
in a method call, it tells us which Invisible Wallet to use. It could be your internaluserId
value, or a new arbitrary and unique value you link to theuserId
.secret
: Your internal secret for a wallet. ThesessionToken
you generate with it is combined with Shinami data to obtain a signature from the associated wallet. Ideally it would be different for each wallet so that if onesecret
is compromised the rest are not.


Tutorial with E2E sample code
Check out our TypeScript tutorial for more code samples and details on the end-to-end flow of creating and using Invisible Wallets to execute sponsored transactions.Methods
key_createSession
For security purposes, you must generate a session token before you create a wallet, or sign/execute transactions. Session tokens are valid and can be reused for 10 minutes. You may also use an instance ofShinamiWalletSigner
to manage session token generation and refreshes for a given wallet. This is shown in the methods below that have a sessionToken
parameter in an additional sample code tab.
Request Parameters
Name | Type | Description |
---|---|---|
secret | string | Used to encrypt and decrypt a wallet’s private key. Therefore, it must always be used with the same walletId and cannot be changed in the future (see walletId and secret pairing) |
{{name}}
with the actual value for that name.
Type | Description |
---|---|
string | sessionToken corresponding to the provided secret . Valid and can be reused for 10 minutes. |
wal_createWallet
Creates a new Shinami Invisible Wallet you control, but does not yet initialize the address on an Aptos network (e.g. Mainnet). Generally, you can wait to initialize a wallet if you wish (see more in the description ofwal_initializeWalletOnChain
).
Wallet creation limit
On the free tier you have a limit of wallet creations per month as shown on the “Aptos Wallet Services” tab of the billing page in your dashboard (where you can also see how to upgrade if needed). If you hit this limit, you will get a JSON-RPC code -32012
and should not retry. All other wallet operations will still work for the month, like signing with wallets you’ve already created.
Request Parameters
Name | Type | Description |
---|---|---|
walletId | string | A unique ID you maintain for the wallet. Can be based on your internal user IDs. Note: you cannot change this value in the future, so do not use a value that you or your users might change, such as a editable username. |
sessionToken | string | The token generated by shinami_key_createSession with the unalterable secret you will permanently associate with this walletId (and, ideally, only this walletId). |
{{name}}
with the actual value for that name.
Name | Type | Description |
---|---|---|
accountAddress | cURL stringSDK AccountAddress | The Aptos address of created wallet. |
wal_initializeWalletOnChain
Initializes a Shinami Invisible Wallet on the Aptos network the Gas Station rights of your access key is associated with (e.g. Mainnet). This comes after a call towal_createWallet
but is not always needed. That’s because:
- Initialization happens automatically if you send a transaction with an uninitialized wallet as the sender (e.g. calling
wal_executeGaslessTransaction
) . - Also, if something is transferred to an address you control the keys for (e.g. an NFT) before you initialize it, you’ll still be able to control that NFT after you initialize it.
Name | Type | Description |
---|---|---|
walletId | string | A unique ID you maintain for the wallet. Can be based on your internal user IDs. Note: you cannot change this value in the future, so do not use a value that you or your users might change, such as a editable username. |
sessionToken | string | The token generated by shinami_key_createSession with the unalterable secret you will permanently associate with this walletId (and, ideally, only this walletId). |
{{name}}
with the actual value for that name.
Name | Type | Description |
---|---|---|
accountAddress | cURL stringSDK AccountAddress | The Aptos address of created wallet. |
wal_createWalletOnChain
Creates and initializes a Shinami Invisible Wallet onto the Aptos chain. Generally, you can wait to initialize a wallet if you wish (see more in the description ofwal_initializeWalletOnChain
). We provide a variety of wallet creation and initialization methods to give you flexibility.
Wallet creation limit
On the free tier you have a limit of wallet creations per month as shown on the “Aptos Wallet Services” tab of the billing page in your dashboard (where you can also see how to upgrade if needed). If you hit this limit, you will get a JSON-RPC code -32012
and should not retry. All other wallet operations will still work for the month, like signing with wallets you’ve already created.
Access Key Requirements: In addition to Wallet Services rights, making this request requires an access key with Node Service rights and Gas Station rights for the Aptos network you wish to initialize the wallet on. This is because initialization involves submitting a basic transaction with the Invisible Wallet as the sender and the gas fee sponsored by your Gas Station fund. See how to make one here. See also the next section:
Gas Station fund required: You need a Gas Station fund with APT in order to sponsorship transactions for an Invisible Wallet, including the transaction that explicitly initializes it on chain. For information on how to set this up, see the Aptos Gas Station FAQ page in our Help Center.
Shinami sponsorship fees: See our Aptos Billing FAQ.
Request Parameters
Name | Type | Description |
---|---|---|
walletId | string | A unique ID you maintain for the wallet. Can be based on your internal user IDs. Note: you cannot change this value in the future, so do not use a value that you or your users might change, such as a editable username. |
sessionToken | string | The token generated by shinami_key_createSession with the unalterable secret you will permanently associate with this walletId (and, ideally, only this walletId). |
{{name}}
with the actual value for that name.
Name | Type | Description |
---|---|---|
accountAddress | cURL stringSDK AccountAddress | The Aptos address of created wallet. |
wal_getWallet
Gets the address of an existing Invisible Wallet, regardless of whether it is initialized or uninitialized on chain. Request ParametersName | Type | Description |
---|---|---|
walletId | string | A unique ID you maintain for the wallet. Can be based on your internal user IDs. Note: you cannot change this value in the future, so do not use a value that you or your users might change, such as a editable username. |
{{name}}
with the actual value for that name.
Name | Type | Description |
---|---|---|
accountAddress | cURL stringSDK AccountAddress | The Aptos address of created wallet. |
wal_signTransaction
Use an initialized Shinami Invisible Wallet to sign a transaction. When the wallet is the sender and you are sponsoring as the feePayer, usewal_executeGaslessTransaction
, which does all of: sign, sponsor, and submit the transaction to the Aptos network.
Request Parameters
Name | Type | Description |
---|---|---|
walletId | string | A unique ID you maintain for the wallet. Can be based on your internal user IDs. Note: you cannot change this value in the future, so do not use a value that you or your users might change, such as a editable username. |
sessionToken | string | The token generated by shinami_key_createSession with the unalterable secret you will permanently associate with this walletId (and, ideally, only this walletId). |
SDK-only transaction | AnyRawTransaction | A SimpleTransaction or a MultiAgentTransaction that does not have a fee payer. You can find an example of building a transaction in our tutorial |
cURL-only rawTransaction | Hex string | unsigned byte array | BCS-serialized RawTransaction. Can be passed either as an unsigned byte array or a Hex string. For a Python example of how to serialize this to send to Shinami, see the Aptos Python SDK: rawTransaction tab of the Example Request Templates. |
cURL-only secondaryAddresses | string[] | (Optional) Required for multi-agent transactions. Array of addresses of the secondary signers for the transaction. Must be in the exact order. |
cURL-only feePayerAddress | string | (Optional) Address of a feepayer for the rawTransaction. |
{{name}}
with the actual value for that name.
Name | Type | Description |
---|---|---|
signature | cURL Unsigned byte arraySDK AccountAuthenticator | The Invisible Wallet’s signature for the transaction. |
- The Invisible wallet must be initialized on chain.
- If you attempt to sign immediately after initializing a wallet you may get an error that the address was not found on chain, as it take a couple of seconds for the initialization to be processed by the Aptos blockchain.
wal_executeGaslessTransaction
Sponsors, signs, and executes a gasless transaction from a Shinami Invisible Wallet. This is a convenient end-to-end method for submitting sponsored transactions to the Aptos chain as opposed to doing all the steps individually. Access Key Requirements: In addition to Wallet Services rights, making this request requires an access key with Gas Station and Node Service rights for the Aptos network you wish to sponsor and execute the transaction on. See how to make one here. See also the next section: Gas Station fund required: You need a Gas Station fund with APT in order to sponsorship transactions for an Invisible Wallet. For information on how to set this up, see the Aptos Gas Station FAQ page in our Help Center. Shinami sponsorship fees: See our Aptos Billing FAQ. Request ParametersName | Type | Description |
---|---|---|
walletId | string | A unique ID you maintain for the wallet. Can be based on your internal user IDs. Note: you cannot change this value in the future, so do not use a value that you or your users might change, such as a editable username. |
sessionToken | string | The token generated by shinami_key_createSession with the unalterable secret you will permanently associate with this walletId (and, ideally, only this walletId). |
SDK-only transaction | AnyRawTransaction | A SimpleTransaction or a MultiAgentTransaction . You can find an example of building a transaction in our tutorial |
cURL-only rawTransaction | Hex string | unsigned byte array | BCS-serialized RawTransaction. Can be passed either as an unsigned byte array or a Hex string. For a Python example of how to serialize this to send to Shinami, see the Aptos Python SDK: rawTransaction tab of the Example Request Templates. |
secondarySigners | SDK AccountAuthenticator[]cURL [“address” : hex string, “signature”: BCS-serialized AccountAuthenticator(Can be passed either as an unsigned byte array or a hex string.)] | (optional) Array of additional signers and their signatures. Must be in the exact order. Required for multi-agent transactions. |
{{name}}
with the actual value for that name.
Name | Type | Description |
---|---|---|
pendingTransaction | cURL object (same shape as a PendingTransactionResponse )SDK PendingTransactionResponse | The submitted transaction waiting in mempool. |