Files
lez-programs/apps/amm/src/AmmClient.cpp
r4bbit b2753aa0c9 feat(apps/amm): add create-pool / new liquidity position flow
Add a "Create Pool" flow to the AMM app that lets a user open a new
liquidity position — seeding a pool's initial liquidity — from token
selection and amount entry, through a confirmation dialog, to on-chain
submission.

- client crate (apps/amm/client): pure, testable protocol logic — account
  decoding, pair/position modelling, and quote/plan computation — exposed to
  the app over a C ABI (config/networks.json drives network selection).
- C++ runtime + backend: AmmClient, ActiveNetwork, and NewPositionRuntime,
  wired into AmmUiBackend (new resolve/quote/submit slots).
- QML flow: NewPositionForm, NewPositionFlow state, NewPositionConfirmation-
  Dialog, TokenSelectorModal, and reusable Amm* presentational components
  (theme, surfaces, buttons) + AmountMath.js.
- tests: C++ (NewPositionRuntimeTest, ActiveNetworkTest) and QML
  (tst_NewPositionForm, tst_LiquidityPage, tst_TokenAmountInput, …).
2026-07-24 14:00:42 +02:00

72 lines
2.1 KiB
C++

#include "AmmClient.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonParseError>
#include "amm_client.h"
namespace {
using Operation = char* (*)(const char*);
AmmClientResult call(Operation operation, const QJsonObject& request)
{
const QByteArray payload = QJsonDocument(request).toJson(QJsonDocument::Compact);
char* raw = operation(payload.constData());
if (!raw) {
qWarning() << "AmmClient: bundled client returned a null response";
return {};
}
const QByteArray response(raw);
amm_free(raw);
QJsonParseError parseError;
const QJsonDocument document = QJsonDocument::fromJson(response, &parseError);
if (parseError.error != QJsonParseError::NoError || !document.isObject()) {
qWarning() << "AmmClient: bundled client returned invalid JSON";
return {};
}
const QJsonObject envelope = document.object();
if (!envelope.value(QStringLiteral("ok")).toBool()) {
qWarning() << "AmmClient: bundled client failure:"
<< envelope.value(QStringLiteral("error")).toString();
return {};
}
if (!envelope.value(QStringLiteral("value")).isObject()) {
qWarning() << "AmmClient: bundled client value is not an object";
return {};
}
return { true, envelope.value(QStringLiteral("value")).toObject() };
}
}
AmmClientResult BundledAmmClient::configId(const QJsonObject& request) const
{
return call(amm_config_id, request);
}
AmmClientResult BundledAmmClient::tokenIds(const QJsonObject& request) const
{
return call(amm_token_ids, request);
}
AmmClientResult BundledAmmClient::pairIds(const QJsonObject& request) const
{
return call(amm_pair_ids, request);
}
AmmClientResult BundledAmmClient::context(const QJsonObject& request) const
{
return call(amm_context, request);
}
AmmClientResult BundledAmmClient::quote(const QJsonObject& request) const
{
return call(amm_quote, request);
}
AmmClientResult BundledAmmClient::plan(const QJsonObject& request) const
{
return call(amm_plan, request);
}