Technical Architecture
This documentation describes part of Palma Network's tech stack, architecture, and public code examples. It is intentionally scoped to exclude sensitive logic or internal endpoints.
π§ Backend Architecture
π§± Tech Stack
Runtime: Node.js
Framework: Express.js
Database: MongoDB with Mongoose
Smart Contracts: Solidity (EVM chains)
Key Libraries:
ethers
,web3
(EVM interaction)jsonwebtoken
(auth)cors
,express
,axios
,dotenv
mongo-sanitize
(security)crypto
(signature utils)
π Modular Routes Example
app.use(cors());
app.use(express.json());
app.use('/api/v1/auth', authRouter);
app.use('/api/v1/user', userRouter);
app.use('/api/v1/limitOrder', limitOrderRouter);
app.use('/api/v1/swap', swapRouter);
app.use('/api/v1/twap', twapRouter);
limitOrderRouter.post('/all', limitOrderController.all);
limitOrderRouter.post('/info', limitOrderController.info);
limitOrderRouter.post('/tokens', limitOrderController.tokens);
limitOrderRouter.post('/chart', limitOrderController.chart);
limitOrderRouter.post('/create', limitOrderController.create);
limitOrderRouter.post('/edit', limitOrderController.edit);
limitOrderRouter.post('/cancel', limitOrderController.cancel);
π Token Info Example (Simplified)
async function info(req, res) {
try {
const data = validation.validateData({
tknAddress: { type: 'wallet', required: true },
tknAddressTo: { type: 'wallet', required: false, default: '0x0...' },
amountIn: { type: 'float', required: false, default: 1 },
chain: { type: 'string', required: true },
gas: { type: 'int', required: false, default: 0 },
txRepeating: { type: 'int', required: false, default: 1 },
}, req.body);
const tknInfo = await web3.getInfoByTokenAddr(
data.chain, data.tknAddress, false,
data.tknAddressTo, data.amountIn
);
const gasData = await web3.getDepositAmountWei(
data.chain, data.tknAddress,
Number(data.amountIn), Number(data.gas),
data.txRepeating
);
network.sendOk(res, {
...tknInfo,
gas: gasData.gas.toString(),
amountWeiDeposit: gasData.amount.toString(),
amountWeiFee: gasData.fee_amount.toString(),
usdValue: gasData.usdValue.toString(),
});
} catch (e) {
network.sendErr(res, e.message);
}
}
π JWT Auth Middleware
import jwt from 'jsonwebtoken';
import User from "../core/databaseSchema/User.js";
const verifyAuthToken = async (headers) => {
if (!headers.authorization) throw Error("Invalid token");
const token = headers.authorization.replace("Bearer ", "");
const verified = jwt.verify(token, process.env.JWT_SECRET_KEY);
const timestamp = Math.floor(Date.now() / 1000);
if ((timestamp - verified.iat) >= process.env.JWT_LIFE_TIME) {
throw Error("Token expired");
}
const usr = await User.findById(verified.id, "-__v");
if (!usr) throw Error("Invalid token");
return usr;
};
export default { verifyAuthToken };
π§ Solidity Example: Generic Swap
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @notice Minimal ERC20 interface
interface IERC20 {
function approve(address spender, uint256 value) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
/// @notice Generic DEX router interface (e.g., for any AMM)
interface IDexRouter {
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
}
/// @notice Basic token swap execution via external router
contract DexSwapExecutor {
function performSwap(
address router,
address[] calldata path,
address recipient,
uint256 amountIn,
uint256 minAmountOut,
uint256 deadlineBuffer
) external returns (uint256[] memory) {
IERC20 inputToken = IERC20(path[0]);
require(inputToken.balanceOf(address(this)) >= amountIn, "Insufficient balance");
require(inputToken.approve(router, amountIn), "Token approval failed");
uint256 deadline = block.timestamp + deadlineBuffer;
return IDexRouter(router).swapExactTokensForTokens(
amountIn,
minAmountOut,
path,
recipient,
deadline
);
}
}
π In Addition
This code is provided for demonstration purposes only and illustrates a basic token swap via an external router. It deliberately omits critical aspects such as access control, comprehensive validation, and internal routing logic to keep the example simple and clear.
In a production environment, all swap operations are securely orchestrated off-chain, incorporating features such as:
Gas optimization to reduce transaction costs
Governance-controlled permissions to ensure robust security
Additional safeguards and logic
These measures guarantee safe, reliable, and efficient execution of swap operations in live systems, enabling our users to perform swaps faster, cheaper, and more securely than anyone else.
π§βπ» Frontend Architecture
π§± Tech Stack
Framework: React
Languages: TypeScript, JavaScript
Build Tool: Vite
Styling: Tailwind CSS
State Management: Zustand
Routing:
@tanstack/react-router
API Tools: Axios, React Query
Wallet/Chain: Wagmi, Viem, ConnectKit
π¦ Key Libraries Used
@radix-ui/*
β UI primitives@tanstack/react-query
β caching & data fetchingwagmi
,viem
β Ethereum wallet & chain interactionzustand
β state storerecharts
β chartingaxios
β REST API callsuniversal-cookie
β cookie handling
π± Swap Page Code (Excerpt)
export default function SwapPage() {
const {
outputToken, inputToken, inputAmount,
setIsQuoteLoading, setOutputAmount,
} = useTokenStore();
const { setSwapOrderPath } = useOrderStore();
const { setTransactionStatus } = useTransactionStatusStore();
const chainId = useChainId();
const { data, isLoading } = useQuery({
queryKey: [
"swapQuote",
outputToken.tokenContract,
inputToken.tokenContract,
inputAmount,
],
queryFn: () =>
getSwapAndLimitTradeInfo({
tknAddress: inputToken.tokenContract,
tknAddressTo: outputToken.tokenContract,
amountIn: inputAmount ?? 0,
chain: chainId,
}),
});
useEffect(() => setIsQuoteLoading(isLoading), [isLoading]);
useEffect(() => setTransactionStatus(TransactionStatuses.START_SWAP), []);
useEffect(() => {
if (!data?.result) return setOutputAmount(0);
const pair = findMaxPriceItem(data.body.pairs);
setOutputAmount(parseFloat(pair.price));
setSwapOrderPath(pair);
}, [data]);
return (
<div className="flex flex-col gap-8">
{/* Inputs and Action Button */}
</div>
);
}
π Wallet Auth (Simplified Flow)
const useAuthStore = create<AuthStore>((set, get) => ({
handleAuth: async (address, signMessageAsync) => {
const { cookiesExist } = get();
if (cookiesExist || get().isAuthInProgress) return;
try {
set({ isAuthInProgress: true, error: null });
const { message, timestamp } = await getWalletSignMessage(address);
const signature = await signMessageAsync({ message });
const loginRes = await loginWithWallet(
address, timestamp, signature, ""
);
if (!loginRes.result) throw new Error("Auth failed");
addPalmaCookies(loginRes.body.accessToken, 86400);
set({ cookiesExist: true, walletAddress: address });
} catch (error) {
set({ error: error.message || "Unknown error" });
} finally {
set({ isAuthInProgress: false });
}
},
}));
π Solana Integration
Palma Network supports Solana alongside EVM chains as part of our multichain aggregation.
β
Features
Read-only SPL token balance checking
WSOL compatibility
Unified quoting interface
Secure connection with official libraries
π§ͺ Public Example: SPL Token Balance
import { Connection, PublicKey } from '@solana/web3.js';
import { getAssociatedTokenAddressSync } from '@solana/spl-token';
const connection = new Connection('https://api.mainnet-beta.solana.com');
async function getTokenBalance(walletAddress: string, tokenMint: string) {
const owner = new PublicKey(walletAddress);
const mint = new PublicKey(tokenMint);
const ata = getAssociatedTokenAddressSync(mint, owner);
const accountInfo = await connection.getTokenAccountBalance(ata);
return {
amount: accountInfo.value.uiAmount,
decimals: accountInfo.value.decimals,
};
}
π Wrapped SOL Helper
const WSOL_MINT = "So11111111111111111111111111111111111111112";
function isWrappedSOL(tokenMint: string) {
return tokenMint === WSOL_MINT;
}
π Disclaimer
The code and examples in this documentation represent only part of Palma Networkβs infrastructure. Critical business logic, private APIs, and internal mechanics have been intentionally excluded for security and confidentiality.
Last updated