Last updated
Last updated
On this page, we demonstrate how to deposit 0.1 XLM and 25 AQUA into a . Scroll to see the complete code.
To perform a deposit, you need to follow these steps:
Specify user secret key, amounts for deposit and pool address: To deposit into a pool, you need your user secret key, the amounts to deposit (specified in stroops) and the pool address. The amounts must be passed to the contract call in the same order as they are indexed in the pool (an example of token sorting ).
# Distributor's secret key (ensure this is kept secure)
user_secret_key = "S..."
# XLM/AQUA pool address
pool_address = "CCY2PXGMKNQHO7WNYXEWX76L2C5BH3JUW3RCATGUYKY7QQTRILBZIFWV"
# 0.1 XLM in stroops
amount_a = 1_000000
# 25 AQUA in stroops
amount_b = 25_0000000
// Distributor's secret key (ensure this is kept secure)
const userSecretKey = "S...";
// XLM/AQUA pool address
const poolAddress = "CCY2PXGMKNQHO7WNYXEWX76L2C5BH3JUW3RCATGUYKY7QQTRILBZIFWV"
// 0.1 XLM in stroops
const amountA = 1000000;
// 25 AQUA in stroops
const amountB = 250000000;
Make a contract call to the pool's "deposit" method.
def execute_deposit():
# Initialize Soroban and Horizon servers
server = SorobanServer(SOROBAN_SERVER_RPC)
horizon_server = Server(HORIZON_SERVER)
# Load distributor's keypair using the secret key
keypair = Keypair.from_secret(user_secret_key)
# Load the distributor's account information from Soroban server
account = server.load_account(keypair.public_key)
# Build the deposit transaction
tx_builder = TransactionBuilder(
source_account=account,
network_passphrase=NETWORK_PASSPHRASE,
base_fee=1000000 # Set base fee; adjust as necessary
).set_timeout(3600) # Set transaction timeout
# Append the invoke_contract_function operation for deposit
tx = tx_builder.append_invoke_contract_function_op(
contract_id=pool_address,
function_name="deposit",
parameters=[
Address(keypair.public_key).to_xdr_sc_val(), # Distributor's address
scval.to_vec([
scval.to_uint128(amount_a), # Amount of XLM to deposit
scval.to_uint128(amount_b), # Amount of AQUA to deposit
]),
scval.to_uint128(0), # Additional parameter (e.g., minimum shares)
],
).build()
# Prepare and sign the transaction
prepared_tx = server.prepare_transaction(tx)
prepared_tx.sign(keypair)
# Submit the transaction to the Horizon server
tx_response = horizon_server.submit_transaction(prepared_tx)
# Parse the transaction metadata to extract results
transaction_meta = xdr.TransactionMeta.from_xdr(tx_response['result_meta_xdr'])
tx_result = transaction_meta.v3.soroban_meta.return_value
if not tx_result:
raise RuntimeError("Transaction did not return a result. Deposit failed.")
# Extract deposited amounts and shares from the transaction result
deposit_a, deposit_b = map(u128_to_int, [r.u128 for r in tx_result.vec.sc_vec[0].vec.sc_vec])
shares_amount = u128_to_int(tx_result.vec.sc_vec[1].u128)
print("Deposit successful!")
print(f"Deposited Amounts: Token A = {deposit_a}, Token B = {deposit_b}")
print(f"Received Shares: {shares_amount}")
async function executeDeposit() {
const sorobanServer = new rpc.Server(sorobanServerUrl);
const horizonServer = new Horizon.Server(horizonServerUrl);
const amountAU128 = new XdrLargeInt('u128', amountA.toFixed()).toU128();
const amountBU128 = new XdrLargeInt('u128', amountB.toFixed()).toU128();
const minimumShares = new XdrLargeInt('u128', '1').toU128(); // 0.0000001
const keypair = Keypair.fromSecret(userSecretKey);
// Load the distributor's account information from Soroban server
const account = await sorobanServer.getAccount(keypair.publicKey());
const contract = new Contract(poolAddress);
// Build the deposit transaction
const tx = new TransactionBuilder(account, {
fee: BASE_FEE,
networkPassphrase: Networks.PUBLIC,
})
// Append the invoke_contract_function operation for deposit
.addOperation(contract.call(
'deposit',
xdr.ScVal.scvAddress(Address.fromString(keypair.publicKey()).toScAddress()), // Distributor's address
xdr.ScVal.scvVec([amountAU128, amountBU128]), // Amounts of Token A and Token B to deposit
minimumShares, // Additional parameter (e.g., minimum shares)
)).setTimeout(TimeoutInfinite).build();
// Prepare and sign the transaction
const preparedTx = await sorobanServer.prepareTransaction(tx);
preparedTx.sign(keypair);
// Submit the transaction to the Horizon server
const result = await horizonServer.submitTransaction(preparedTx);
// Parse the transaction metadata to extract results
const meta = (await sorobanServer.getTransaction(result.id)).resultMetaXdr;
const returnValue = meta.v3().sorobanMeta().returnValue();
// Extract deposited amounts and shares from the transaction result
const [deposited, share] = returnValue.value();
const [depositedA, depositedB] = deposited.value().map(value => u128ToInt(value.value()));
const shareValue = u128ToInt(share.value());
console.log('Deposit successful!');
console.log(`Deposited Amounts: Token A = ${depositedA / 1e7}, Token B = ${depositedB / 1e7}`);
console.log(`Received Shares: ${shareValue / 1e7}`);
}
This code deposits 0.1 XLM and 25 AQUA to the pool with Aquarius AMM on mainnet.
To successfully execute the code, provide the secret key of a Stellar account with at least 5 XLM and 25 AQUA.
# deposit.py
from typing import List
from stellar_sdk import Address, Keypair, scval, SorobanServer, xdr, TransactionBuilder, Server, Network
from stellar_sdk.xdr import UInt128Parts
# Step 1. Specify user secret key, amounts for deposit and pool address
# Distributor's secret key (ensure this is kept secure)
user_secret_key = "S..."
# XLM/AQUA pool address
pool_address = "CCY2PXGMKNQHO7WNYXEWX76L2C5BH3JUW3RCATGUYKY7QQTRILBZIFWV"
# 0.1 XLM in stroops
amount_a = 1_000000
# 25 AQUA in stroops
amount_b = 25_0000000
# ==========================
# Configuration Variables
# ==========================
# Soroban and Horizon server RPC endpoints
SOROBAN_SERVER_RPC = 'https://mainnet.sorobanrpc.com'
HORIZON_SERVER = 'https://horizon.stellar.org'
# Stellar network passphrase
NETWORK_PASSPHRASE = Network.PUBLIC_NETWORK_PASSPHRASE
# ==========================
# Utility Functions
# ==========================
def u128_to_int(value: UInt128Parts) -> int:
"""
Converts UInt128Parts from Stellar's XDR to a Python integer.
Args:
value (UInt128Parts): UInt128Parts object from Stellar SDK.
Returns:
int: Corresponding Python integer.
"""
return (value.hi.uint64 << 64) + value.lo.uint64
# ==========================
# Deposit Function
# ==========================
# Step 2. Make a contract call to the pool's "deposit" method.
def execute_deposit():
# Initialize Soroban and Horizon servers
server = SorobanServer(SOROBAN_SERVER_RPC)
horizon_server = Server(HORIZON_SERVER)
# Load distributor's keypair using the secret key
keypair = Keypair.from_secret(user_secret_key)
# Load the distributor's account information from Soroban server
account = server.load_account(keypair.public_key)
# Build the deposit transaction
tx_builder = TransactionBuilder(
source_account=account,
network_passphrase=NETWORK_PASSPHRASE,
base_fee=1000000 # Set base fee; adjust as necessary
).set_timeout(3600) # Set transaction timeout
# Append the invoke_contract_function operation for deposit
tx = tx_builder.append_invoke_contract_function_op(
contract_id=pool_address,
function_name="deposit",
parameters=[
Address(keypair.public_key).to_xdr_sc_val(), # Distributor's address
scval.to_vec([
scval.to_uint128(amount_a), # Amount of XLM to deposit
scval.to_uint128(amount_b), # Amount of AQUA to deposit
]),
scval.to_uint128(0), # Additional parameter (e.g., minimum shares)
],
).build()
# Prepare and sign the transaction
prepared_tx = server.prepare_transaction(tx)
prepared_tx.sign(keypair)
# Submit the transaction to the Horizon server
tx_response = horizon_server.submit_transaction(prepared_tx)
# Parse the transaction metadata to extract results
transaction_meta = xdr.TransactionMeta.from_xdr(tx_response['result_meta_xdr'])
tx_result = transaction_meta.v3.soroban_meta.return_value
if not tx_result:
raise RuntimeError("Transaction did not return a result. Deposit failed.")
# Extract deposited amounts and shares from the transaction result
deposit_a, deposit_b = map(u128_to_int, [r.u128 for r in tx_result.vec.sc_vec[0].vec.sc_vec])
shares_amount = u128_to_int(tx_result.vec.sc_vec[1].u128)
print("Deposit successful!")
print(f"Deposited Amounts: Token A = {deposit_a}, Token B = {deposit_b}")
print(f"Received Shares: {shares_amount}")
# ==========================
# Entry Point
# ==========================
if __name__ == "__main__":
execute_deposit()
const StellarSdk = require('@stellar/stellar-sdk');
const {
Address,
Contract,
TransactionBuilder,
rpc,
Horizon,
BASE_FEE,
Networks,
xdr,
TimeoutInfinite,
XdrLargeInt,
Keypair,
} = StellarSdk;
// Step 1. Specify user secret key, amounts for deposit and pool address
// Distributor's secret key (ensure this is kept secure)
const userSecretKey = "S...";
// XLM/AQUA pool address
const poolAddress = "CCY2PXGMKNQHO7WNYXEWX76L2C5BH3JUW3RCATGUYKY7QQTRILBZIFWV"
// 0.1 XLM in stroops
const amountA = 1000000;
// 25 AQUA in stroops
const amountB = 250000000;
// ==========================
// Configuration Variables
// ==========================
// Soroban and Horizon server RPC endpoints
const sorobanServerUrl = 'https://mainnet.sorobanrpc.com';
const horizonServerUrl = 'https://horizon.stellar.org';
// ==========================
// Utility Functions
// ==========================
function u128ToInt(value) {
/**
* Converts UInt128Parts from Stellar's XDR to a JavaScript number.
*
* @param {Object} value - UInt128Parts object from Stellar SDK, with `hi` and `lo` properties.
* @returns {number|null} Corresponding JavaScript number, or null if the number is too large.
*/
const result = (BigInt(value.hi()._value) << 64n) + BigInt(value.lo()._value);
// Check if the result is within the safe integer range for JavaScript numbers
if (result <= BigInt(Number.MAX_SAFE_INTEGER)) {
return Number(result);
} else {
console.warn("Value exceeds JavaScript's safe integer range");
return null;
}
}
// ==========================
// Deposit Function
// ==========================
// Step 2. Make a contract call to the pool's "deposit" method.
async function executeDeposit() {
const sorobanServer = new rpc.Server(sorobanServerUrl);
const horizonServer = new Horizon.Server(horizonServerUrl);
const amountAU128 = new XdrLargeInt('u128', amountA.toFixed()).toU128();
const amountBU128 = new XdrLargeInt('u128', amountB.toFixed()).toU128();
const minimumShares = new XdrLargeInt('u128', '1').toU128(); // 0.0000001
const keypair = Keypair.fromSecret(userSecretKey);
// Load the distributor's account information from Soroban server
const account = await sorobanServer.getAccount(keypair.publicKey());
const contract = new Contract(poolAddress);
// Build the deposit transaction
const tx = new TransactionBuilder(account, {
fee: BASE_FEE,
networkPassphrase: Networks.PUBLIC,
})
// Append the invoke_contract_function operation for deposit
.addOperation(contract.call(
'deposit',
xdr.ScVal.scvAddress(Address.fromString(keypair.publicKey()).toScAddress()), // Distributor's address
xdr.ScVal.scvVec([amountAU128, amountBU128]), // Amounts of Token A and Token B to deposit
minimumShares, // Additional parameter (e.g., minimum shares)
)).setTimeout(TimeoutInfinite).build();
// Prepare and sign the transaction
const preparedTx = await sorobanServer.prepareTransaction(tx);
preparedTx.sign(keypair);
// Submit the transaction to the Horizon server
const result = await horizonServer.submitTransaction(preparedTx);
// Parse the transaction metadata to extract results
const meta = (await sorobanServer.getTransaction(result.id)).resultMetaXdr;
const returnValue = meta.v3().sorobanMeta().returnValue();
// Extract deposited amounts and shares from the transaction result
const [deposited, share] = returnValue.value();
const [depositedA, depositedB] = deposited.value().map(value => u128ToInt(value.value()));
const shareValue = u128ToInt(share.value());
console.log('Deposit successful!');
console.log(`Deposited Amounts: Token A = ${depositedA / 1e7}, Token B = ${depositedB / 1e7}`);
console.log(`Received Shares: ${shareValue / 1e7}`);
}
// ==========================
// Entry Point
// ==========================
executeDeposit();
Example of code that deposits liquidity into Aquarius pool