Setup
Antes de fazer qualquer coisa, a Mercatto precisa existir na Ishtaran: uma Organization, uma Application para abrigar sua integração, uma Environment, e uma chave para autenticar. Uma chamada resolve as quatro coisas.
const owner = createClient();
const signup = await owner.auth.signUp(`Mercatto ${runId}`, emails.owner, STORY_PASSWORD);
const mercatto = createClient(signup.apiKeyPlainText!);
Resultado
{
"organizationId": "…",
"applicationId": "…",
"environmentId": "…",
"apiKeyPlainText": "isht_sandbox_…"
}
Dois clients saem desse passo, e a Mercatto guarda os dois:
owner— uma sessão de Member. Um punhado de operações reais mais adiante exigem especificamente isso, não uma API Key (veja Architecture).mercatto— a Application API Key. Tudo o mais usa essa, do mesmo jeito que qualquer integrador real usaria.
O que aconteceu por baixo dos panos
auth.signUp() → OrganizationTenancy cria a Organization, sua Application padrão, a
Environment de Sandbox dessa Application, e uma primeira API Key — atomicamente, uma única
chamada HTTP real. O Asset Network em que a Mercatto vai operar (USDT em Tron, no Sandbox) não
está hardcoded: setup.ts procura por símbolo/código de rede, do mesmo jeito que um integrador
real faria ao apontar para um Sandbox que ele mesmo não semeou.
async function resolveUsdtTronAssetNetworkId(owner) {
const assetNetworks = await owner.assetNetworkCatalog.listAssetNetworks();
for (const candidate of assetNetworks) {
const [asset, network] = await Promise.all([
owner.assetNetworkCatalog.getAsset(candidate.assetId),
owner.assetNetworkCatalog.getNetwork(candidate.networkId),
]);
if (asset.symbol === 'USDT' && network.code === 'tron') return candidate.assetNetworkId;
}
throw new Error('No USDT/Tron Asset Network found in this Sandbox.');
}
assetNetworkCatalog é real, mas — assim como workflows e accounts.authorizeApplication —
hoje é exclusivo de Member, inalcançável com uma API Key. É por isso que essa consulta roda com
owner, não com mercatto.