Sending Transactions & Viewing History
Sphere enables your application to easily send cryptocurrency transactions on behalf of users and to retrieve their transaction history. This functionality is crucial for any application dealing with digital asset transfers.
This page covers:
- Sending tokens (currently, all sends are processed as gasless transactions).
- Fetching a user's transaction history.
- Getting an estimate of transaction fees.
Prerequisites
Before sending transactions or fetching history, ensure:
- User Authentication: The user on whose behalf the transaction is being made, or whose history is being fetched, must be authenticated.
- SDK Authenticated: Your Sphere SDK instance must be authenticated with the user's
accessToken
.
Refer to Creating & Accessing User Wallets or OTP Verification & Session Management for details on establishing an authenticated SDK session.
import Sphere, {
Environment,
ChainName,
TokenSymbol,
TransactionRequest,
TransactionResponse,
TransactionHistoryRequest,
TransactionHistory,
TransactionHistoryResponse,
TransactionType,
} from "@stratosphere-network/wallet";
const sphere = new Sphere({
apiKey: "YOUR_API_KEY", // Your project API key
environment: Environment.DEVELOPMENT,
});
// Example: After user login, you get an accessToken
// sphere.setBearerToken("USER_ACCESS_TOKEN");
1. Sending a Transaction (sphere.transactions.send
)
This method allows an authenticated user to send a specified amount of a token to a recipient address on a given chain. Currently, Sphere processes all send
transactions as gasless, meaning the Stratosphere Network covers the network fees for the user, simplifying their experience. A fee is charged to the user in the token they are transferring to cover this. (See Transaction Fees for more details).
Intuition: This is like making a bank transfer where the service fee is deducted from the transfer amount itself, and you don't need a separate balance for network charges. You specify the recipient, amount, and currency (token & chain).
Flow:
- Your application gathers transaction details from the user (recipient, amount, token, chain).
- It calls
sphere.transactions.send()
with these details (thetype
will effectively begasless
). - The Sphere SDK communicates with the Stratosphere Network, which validates the request, processes the gas sponsoring, and submits the transaction on the blockchain.
- A response is returned with the transaction hash and status message.
Diagram: Sending a Transaction (Gasless)
SDK Usage: Sending Tokens
async function sendTokens(
toAddress: string,
value: string, // Amount as a string, e.g., "0.5"
tokenSymbol: TokenSymbol,
chainName: ChainName
// transactionType parameter is omitted as only 'gasless' is currently supported implicitly
): Promise<TransactionResponse | null> {
if (!sphere.isAuthenticated()) {
console.error("SDK is not authenticated. Please log in the user first.");
return null;
}
try {
const requestPayload: TransactionRequest = {
to: toAddress,
value: value,
token: tokenSymbol,
chain: chainName,
type: "gasless", // Explicitly setting, though it's the only supported mode
};
console.log(
`Sending ${value} ${tokenSymbol} to ${toAddress} on ${chainName} (gasless)...`
);
const response = await sphere.transactions.send(requestPayload);
if (response && response.transactionHash) {
console.log("Transaction successful!");
console.log(" Message:", response.message);
console.log(" Transaction Explorer URL:", response.transactionHash);
return response;
} else {
console.error(
"Failed to send transaction. Response was empty or missing transaction hash."
);
return null;
}
} catch (error) {
console.error("Error sending transaction:", error);
throw error;
}
}
// Example Usage:
/*
// Send 0.1 USDC on Polygon (processed as gasless)
sendTokens("0xRecipientWalletAddress...", "0.1", TokenSymbol.USDC, ChainName.POLYGON)
.then(response => {
if (response) {
console.log("Transaction complete! View at:", response.transactionHash);
// The transactionHash is already the full explorer URL
// e.g., https://polygonscan.com/tx/0x123...
}
})
.catch(err => console.error("Send transaction failed:", err));
*/
TransactionRequest
Parameters:
to: string
: The recipient's wallet address.value: string
: The amount of the token to send, as a string (e.g., "10.5", "0.001").token: TokenSymbol
: The symbol of the token being sent (e.g.,TokenSymbol.USDC
,TokenSymbol.ETH
).chain: ChainName
: The chain on which the transaction will occur.type?: TransactionType
: Optional. Currently, only"gasless"
is effectively supported, where the Stratosphere Network covers gas fees. Specifying"normal"
may not have a different effect at this time or could result in an error if not yet implemented. It's safest to assume or specify"gasless"
.intent?: "unlock"
: Optional. Use this if the transaction's purpose is to approve or unlock tokens for another contract (e.g., before a swap on a DEX).
TransactionResponse
The response from a successful send operation includes:
interface TransactionResponse {
message: string; // Status message about the transaction (e.g., "Transaction confirmed!")
transactionHash: string; // Full block explorer URL for the transaction (e.g., "https://etherscan.io/tx/0x...")
}
The transactionHash
field contains the complete block explorer URL for your convenience. It automatically points to the appropriate explorer based on the chain used (e.g., Etherscan for Ethereum, PolygonScan for Polygon, BeraScan for Berachain, etc.).
2. Getting Transaction History (sphere.transactions.getHistory
)
This method allows you to retrieve a paginated list of past transactions for the authenticated user. The response includes both the transaction data and pagination information for easy navigation through large transaction histories.
Intuition: This is like viewing your bank statement. You can see a list of incoming and outgoing transactions, amounts, and dates.
Flow:
- Your application calls
sphere.transactions.getHistory()
, optionally providing pagination parameters. - The Sphere SDK communicates with the Stratosphere Network, which queries its records for the user's transaction data.
- A response containing a list of transactions and pagination information is returned.
Diagram: Getting Transaction History
SDK Usage: Fetching History
async function fetchTransactionHistory(
limit: number = 10,
page: number = 1,
token?: string,
chain?: string
): Promise<TransactionHistoryResponse | null> {
if (!sphere.isAuthenticated()) {
console.error("SDK is not authenticated. Please log in the user first.");
return null;
}
try {
const requestPayload: TransactionHistoryRequest = {
limit: limit,
page: page,
token: token, // Optional: Filter by specific token (e.g., "USDC")
chain: chain, // Optional: Filter by specific chain (e.g., "ethereum")
};
console.log(
`Fetching transaction history (page ${page}, limit ${limit})...`
);
if (token) console.log(` Filtering by token: ${token}`);
if (chain) console.log(` Filtering by chain: ${chain}`);
const response = await sphere.transactions.getHistory(requestPayload);
if (response && response.transactions.length > 0) {
console.log(
`Successfully fetched ${response.transactions.length} transactions:`
);
console.log(
`Pagination: Page ${response.pagination.currentPage} of ${response.pagination.pages} (${response.pagination.total} total)`
);
response.transactions.forEach((tx) => {
console.log(`\n ID: ${tx.id}`);
console.log(` Transaction Hash: ${tx.transactionHash}`);
console.log(` Created: ${new Date(tx.createdAt).toLocaleString()}`);
console.log(` Amount: ${tx.amount} ${tx.token}`);
console.log(` Chain: ${tx.chain}`);
console.log(` To: ${tx.recipientAddress}`);
console.log(` User ID: ${tx.userId}`);
if (tx.currency) {
console.log(` Currency: ${tx.currency}`);
}
});
return response;
} else {
console.log("No transaction history found.");
return {
transactions: [],
pagination: {
total: 0,
pages: 0,
currentPage: page,
perPage: limit,
},
};
}
} catch (error) {
console.error("Error fetching transaction history:", error);
throw error;
}
}
// Example Usage:
/*
// Fetch all transactions
fetchTransactionHistory()
.then(response => {
if (response && response.transactions.length > 0) {
console.log(`Found ${response.transactions.length} transactions`);
console.log(`Total available: ${response.pagination.total}`);
// Update UI with transaction history
}
});
// Fetch USDC transactions on Polygon only
fetchTransactionHistory(20, 1, "USDC", "polygon")
.then(response => {
if (response) {
console.log(`Found ${response.transactions.length} USDC transactions on Polygon`);
console.log(`Page ${response.pagination.currentPage} of ${response.pagination.pages}`);
}
});
*/
TransactionHistoryRequest
Parameters:
limit?: number
: Optional. The number of transactions to return per page.page?: number
: Optional. The page number for pagination.token?: string
: Optional. Filter results by a specific token (e.g., "USDC", "ETH").chain?: string
: Optional. Filter results by a specific chain (e.g., "ethereum", "polygon").
TransactionHistory
Structure:
interface TransactionHistory {
id: string; // Unique identifier for the transaction record
userId: string; // ID of the user who made the transaction
transactionHash: string; // The on-chain transaction hash (e.g., "0x123...")
chain: string; // Blockchain network (e.g., "ethereum", "polygon")
token: string; // Token symbol (e.g., "USDC", "ETH")
currency?: string; // Optional currency information
amount: number; // Amount transferred as a number
recipientAddress: string; // The recipient's wallet address
createdAt: string; // ISO 8601 timestamp of when the transaction was created
}
interface TransactionHistoryResponse {
transactions: TransactionHistory[]; // Array of transaction history items
pagination: {
total: number; // Total number of transactions available
pages: number; // Total number of pages
currentPage: number; // Current page number
perPage: number; // Number of transactions per page
};
}
Note: Unlike the
send()
method which returns thetransactionHash
as a full explorer URL, the transaction history returns the actual on-chain transaction hash. You can construct explorer URLs from this hash based on the chain if needed.
3. Getting Transaction Fee (sphere.transactions.getFee
)
This method allows you to estimate the fee that Sphere will charge for a gasless transaction. This is useful for displaying potential costs to the user before they initiate a transaction. The fee is charged in the token being transferred.
Intuition: This is like asking for a quote for the service fee before committing to a bank transfer. You provide the details of the intended transfer (recipient, amount, token, chain), and the service tells you how much the fee will be in that token.
Flow:
- Your application gathers the potential transaction details from the user (recipient, amount, token, chain).
- It calls
sphere.transactions.getFee()
with these details. - The Sphere SDK communicates with the Stratosphere Network, which calculates the estimated fee based on current network conditions and the transaction parameters.
- A response is returned with the estimated fee amount and the token in which the fee will be charged.
Diagram: Getting Transaction Fee
SDK Usage: Getting Fee
async function getTransactionFee(
recipientAddress: string,
amountToSend: string,
tokenSymbol: string, // Assuming TokenSymbol enum or similar for consistency, but user provided string
chainName: string // Assuming ChainName enum or similar, but user provided string
): Promise<TransactionFeeResponse | null> {
if (!sphere.isAuthenticated()) {
console.error("SDK is not authenticated. Please log in the user first.");
return null;
}
try {
const requestPayload: TransactionFeeRequest = {
recipient: recipientAddress,
amount: amountToSend,
token: tokenSymbol,
chain: chainName,
};
console.log(
`Fetching fee for sending ${amountToSend} ${tokenSymbol} to ${recipientAddress} on ${chainName}...`
);
const response = await sphere.transactions.getFee(requestPayload); // Assuming sphere.transactions.getFee exists
if (response) {
console.log("Fee estimation successful!");
console.log(" Fee Amount:", response.amount);
console.log(" Fee Token:", response.token);
return response;
} else {
console.error("Failed to get transaction fee. Response was empty.");
return null;
}
} catch (error) {
console.error("Error fetching transaction fee:", error);
throw error; // Re-throw the error so the caller can handle it
}
}
// Example Usage:
/*
getTransactionFee("0xRecipientWalletAddress...", "0.1", "USDC", "polygon")
.then(feeResponse => {
if (feeResponse) {
console.log(`Estimated fee: ${feeResponse.amount} ${feeResponse.token}`);
// Update UI with fee information
}
})
.catch(err => console.error("Get fee failed:", err));
*/
TransactionFeeRequest
Parameters:
recipient: string
: The recipient's wallet address.amount: string
: The amount of the token to be sent, as a string (e.g., "10.5", "0.001").token: string
: The symbol of the token to be sent (e.g., "USDC", "ETH").chain: string
: The chain on which the transaction would occur (e.g., "ethereum", "polygon").
TransactionFeeResponse
Structure:
// Transaction Fee Types
export interface TransactionFeeRequest {
recipient: string;
amount: string;
chain: string;
token: string;
}
export interface TransactionFeeResponse {
amount: number; // The estimated fee amount
token: string; // The token in which the fee will be charged (usually the same as the transfer token)
}
Note: The actual method signature within the SDK is
async getFee(request: TransactionFeeRequest): Promise<TransactionFeeResponse>
. TheTransactionFeeRequest
andTransactionFeeResponse
interfaces shown here are based on your provided types. Ensure these types are correctly defined and exported in your SDK.
Important Considerations
- Authentication: All methods require an authenticated SDK.
- Gasless Transactions: For
send
operations, transactions are processed as gasless. The Stratosphere Network facilitates this, and a fee is charged in the transacted token (see Transaction Fees). Future updates might introduce "normal" transactions where the user pays gas directly. - Transaction Explorer URLs: The
send()
method returns atransactionHash
field that contains the full block explorer URL (not just the hash). This URL automatically points to the appropriate explorer for the chain used. The transaction is submitted to the blockchain when you receive the response. - History Scope: Transaction history is sourced from Stratosphere Network records and includes pagination information for efficient data retrieval.
- Error Handling: Implement robust error handling for issues like insufficient balance (after deducting Sphere's fee for gasless), network errors, etc.
Next Steps
- Display transaction history in your application.
- Explore Payment Requests & Send Links.
- Integrate DeFi Swaps.
For comprehensive details, consult the Sphere SDK API reference or community.