Dependencies, commonly used URLs, contract addresses and useful methods
Prerequisites
Before executing scripts, ensure you have Stellar SDK installed:
Python 3.7+: The script is written in Python and requires Python version 3.7 or higher.
Stellar SDK: Install via pip:
pip install stellar-sdk
Node 18+: The script is written in JavaScript and requires Node version 18 or higher.
Stellar SDK: Install via npm or yarn.
npm install @stellar/stellar-sdk
or
yarn add @stellar/stellar-sdk
Constants
Below are some API endpoints and contract addresses that will be used in other code examples.
For Mainnet
# The contract ID of the Aquarius AMM contract
router_contract_id = "CBQDHNBFBZYE4MKPWBSJOPIYLW4SFSXAXUTSXJN76GNKYVYPCKWC6QUK"
# Soroban RPC server address
soroban_rpc_server = "https://mainnet.sorobanrpc.com"
# Horizon server address
horizon_server = "https://horizon.stellar.org"
# Aquarius backend API URL
base_api = "https://amm-api.aqua.network/api/external/v1"
// The contract ID of the Aquarius AMM contract
const routerContractId = "CBQDHNBFBZYE4MKPWBSJOPIYLW4SFSXAXUTSXJN76GNKYVYPCKWC6QUK";
// Soroban RPC server address
const sorobanRpcServer = "https://mainnet.sorobanrpc.com";
// Horizon server address
const horizonServer = "https://horizon.stellar.org";
// Aquarius backend API URL
const baseApi = "https://amm-api.aqua.network/api/external/v1";
For Testnet
# The contract ID of the Aquarius AMM contract
# This updates quarterly, due to testnet reset.
# Address updated on December 2024.
router_contract_id = "CDGX6Q3ZZIDSX2N3SHBORWUIEG2ZZEBAAMYARAXTT7M5L6IXKNJMT3GB"
# Soroban RPC server address
soroban_rpc_server = "https://soroban-testnet.stellar.org:443"
# Horizon server address
horizon_server = "https://horizon-testnet.stellar.org"
# Aquarius backend API URL
base_api = "https://amm-api-testnet.aqua.network/api/external/v1"
// The contract ID of the Aquarius AMM contract
// This updates quarterly, due to testnet reset.
// Address updated on December 2024.
const routerContractId = "CDGX6Q3ZZIDSX2N3SHBORWUIEG2ZZEBAAMYARAXTT7M5L6IXKNJMT3GB";
// Soroban RPC server address
const sorobanRpcServer = "https://soroban-testnet.stellar.org:443";
// Horizon server address
const horizonServer = "https://horizon-testnet.stellar.org";
// Aquarius backend API URL
const baseApi = "https://amm-api-testnet.aqua.network/api/external/v1";
Helper Functions
Common utility methods that will be used in other code examples.
Get Asset Contract Id
To interact with any Soroban assets, you need their smart contract address.
This code snippet demonstrates how to retrieve the contract address of an asset on the Stellar network. The code uses the PUBLIC network by default, but you can switch to the desired network (e.g. TESTNET).
from stellar_sdk import Asset, Network
# Create the native asset
asset = Asset.native()
# Or create a custom asset
# asset = Asset("AQUA", "GBNZILSTVQZ4R7IKQDGHYGY2QXL5QOFJYQMXPKWRRM5PAV7Y4M67AQUA")
# Retrieve the contract ID for the PUBLIC network
contract_id = asset.contract_id(Network.PUBLIC_NETWORK_PASSPHRASE)
print(contract_id)
# Example output:
# "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"
const StellarSdk = require('@stellar/stellar-sdk');
// Create the native asset
const asset = StellarSdk.Asset.native();
// Or create a custom asset
// const asset = new StellarSdk.Asset('AQUA', 'GBNZILSTVQZ4R7IKQDGHYGY2QXL5QOFJYQMXPKWRRM5PAV7Y4M67AQUA');
// Retrieve the contract ID for the PUBLIC network
const contractId = asset.contractId(StellarSdk.Networks.PUBLIC);
console.log(contractId);
// console.log example
// "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"
Get Pool Contract ID and Pool Hash
To interact with an Aquarius pool (e.g. make deposits or direct swaps), you need the address of the pool contract.
One option to find the pool address is to refer to the pool page on Aquarius website, please see below:
In order to receive this information programmatically, please refer to detailed description in the "Get Pools Info" section.
Order Tokens IDs
Most of the time, if an array of token IDs needs to be passed as arguments in a contract call, they should be sorted.
def order_token_ids(tokens: List[xdr.SCVal]) -> List[xdr.SCVal]:
"""
Orders token IDs based on their contract ID to maintain consistency.
Args:
tokens (List[xdr.SCVal]): List of token addresses as SCVal objects.
Returns:
List[xdr.SCVal]: Ordered list of token SCVal objects.
"""
return sorted(tokens, key=lambda token: int(token.address.contract_id.hash.hex(), 16))
function orderTokensIds(tokensIds) {
/**
* Orders token IDs based on their contract ID to maintain consistency.
*
* @param {Array} tokensIds - List of token addresses as SCVal objects.
* @returns {Array} Ordered list of token SCVal objects.
*/
return tokensIds.sort((a, b) => {
const aHash = BigInt('0x' + a.address().contractId().toString('hex'));
const bHash = BigInt('0x' + b.address().contractId().toString('hex'));
// Compare BigInts directly without converting to number
if (aHash < bHash) return -1;
if (aHash > bHash) return 1;
return 0;
});
}
Data Conversion Utilities
Here are methods and code snippets for converting data between basic types and ScVal (Smart Contract Value).
from stellar_sdk import Address, scval
# ================
# Basic => ScVal
# ================
# Contract Id To ScVal
contract_id = "C..."
contract_id_scval = scval.to_address(contract_id)
# Array To ScVal
scval.to_vec([contract_id_scv, contract_id_scv])
# Public Key To ScVal
public_key = "G..."
public_key_scval = scval.to_address(public_key)
# Number To Uint32 ScVal
number_u32_scval = scval.to_uint32(1_000_000)
# Number To Uint128 ScVal
number_u128_scval = scval.to_uint128(1_000_000)
# Hash To ScVal
pool_hash = "a1b2...."
pool_hash_scval = scval.to_bytes(bytes.fromhex(pool_hash))
# ================
# ScVal => Basic
# ================
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 int(value.hi.uint64 << 64) + value.lo.uint64
const StellarSdk = require('@stellar/stellar-sdk');
const binascii = require('binascii');
const { Address, StrKey, XdrLargeInt, xdr } = StellarSdk;
// ================
// Basic => ScVal
// ================
function contractIdToScVal(contractId) {
/**
* Converts a contract ID to a Stellar SCVal (Smart Contract Value) format.
*
* @param {string} contractId - The contract ID to convert.
* @returns {StellarSdk.xdr.ScVal} - The SCVal representation of the contract ID.
*
* @throws {Error} Throws an error if the contract ID is invalid or cannot be decoded.
*/
return Address.contract(StrKey.decodeContract(contractId)).toScVal();
}
function arrayToScVal(array) {
/**
* Converts an array of ScVal objects into a single ScVal vector.
*
* @param {StellarSdk.xdr.ScVal[]} array - An array of ScVal objects to be converted into a vector.
* @returns {StellarSdk.xdr.ScVal} A ScVal object representing the vector.
*/
return xdr.ScVal.scvVec(array);
}
function publicKeyToScVal(pubkey) {
/*
* Converts a Stellar public key string into an ScVal address.
*
* @param {string} pubkey - The Stellar public key to be converted.
* @returns {StellarSdk.xdr.ScVal} An ScVal object representing the address derived from the public key.
*/
return xdr.ScVal.scvAddress(Address.fromString(pubkey).toScAddress());
}
function numberToUint32(number) {
/**
* Converts a number to an ScVal representing a 32-bit unsigned integer (Uint32).
*
* @param {number} number - The number to be converted. Must be a non-negative integer within the range of Uint32 (0 to 2^32 - 1).
* @returns {StellarSdk.xdr.ScVal} An ScVal object representing the 32-bit unsigned integer.
*/
return xdr.ScVal.scvU32(number);
}
function numberToUint128(number) {
/**
* Converts a number to an ScVal representing a 128-bit unsigned integer (Uint128).
*
* @param {number} number - The number to be converted. Must be a non-negative value that fits within the range of Uint128.
* @returns {StellarSdk.xdr.ScVal} An ScVal object representing the 128-bit unsigned integer.
*/
return new XdrLargeInt(
'u128',
number.toFixed(),
).toU128();
}
function bufferToScVal(buffer) {
/**
* Converts a Buffer object into an ScVal representing a byte array.
*
* @param {Buffer} buffer - The Buffer object containing the byte data to be converted.
* @returns {StellarSdk.xdr.ScVal} An ScVal object representing the byte array.
*/
return xdr.ScVal.scvBytes(buffer);
}
hashToScVal(hash) {
/**
* Converts a hexadecimal hash string into an ScVal representing a byte array.
*
* @param {string} hash - The hash string in hexadecimal format to be converted.
* @returns {StellarSdk.xdr.ScVal} An ScVal object representing the byte array derived from the hash.
*/
return xdr.ScVal.scvBytes(Buffer.from(binascii.unhexlify(hash), 'ascii'));
}
// ================
// SvVal => Basic
// ================
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;
}
}