전체 글 보기
6 분 소요

TON 논커스터디얼 스왑: AI 에이전트가 키 없이 토큰 교환하기

AI 에이전트가 TON에서 논커스터디얼 토큰 스왑을 하는 방법. Omniston 기반 get_swap_quote와 build_swap_tx, 서버는 개인키를 보관하지도 서명하지도 않습니다.

TONMCP토큰 스왑논커스터디얼OmnistonAI 에이전트

키를 누가 쥐고 있는가 — AI 에이전트의 TON 논커스터디얼 토큰 스왑에서 가장 중요한 질문

이런 상황을 상상해 봅시다. AI 에이전트에게 시세를 지켜보다가 USDT가 내려가면 GRAM으로 사 모으라고 지시합니다. 에이전트는 시장을 평가하고, 타이밍을 찾고, 거래를 준비합니다. 그리고 바로 여기서 보통은 너무 늦게 떠올리게 되는 질문이 튀어나옵니다. 에이전트가 실제로 스왑을 실행하려면 누군가는 개인키로 트랜잭션에 서명해야 합니다. 그 키는 누가 쥐고 있습니까?

답이 "에이전트가 사용하는 그 서비스"라면, 남의 코드에 자기 돈을 처분할 권한을 넘겨준 셈입니다. 프롬프트 인젝션 한 번, 로그 유출 한 번이면 에이전트는 여러분이 의도한 것과 다른 무언가에 서명합니다. 그리고 여기서 문제의 본질은 "DEX를 어떻게 호출하는가"가 아니라, 에이전트에게 거래를 조립하게 하되 서명은 철저히 사람의 지갑에 남겨두는 방법입니다. 아래에서 AI 에이전트가 TON에서 토큰을 논커스터디얼하게 스왑하는 방법을 살펴보겠습니다.

스왑의 두 부분: 계산은 안전하지만 서명은 그렇지 않습니다

DEX 스왑은 성격이 근본적으로 다른 두 부분으로 나뉩니다. 첫 번째는 계산에 해당하며 안전합니다. 환율을 조회하고, 슬리피지를 계산하고, 트랜잭션 본문을 조립하는 일입니다. 두 번째는 되돌릴 수 없고 위험합니다. 그 본문에 개인키로 서명해 네트워크로 보내는 일입니다. 갈림길은 여기서 생깁니다.

  • 커스터디얼 모델. 에이전트(또는 그 뒤의 서버)가 키를 보관하고 직접 서명합니다. 편리합니다 — 에이전트가 자율적으로 움직이니까요. 하지만 서명 키가 LLM 바로 옆에 놓이게 됩니다. LLM은 본질적으로 비결정적이고, 신뢰할 수 없는 텍스트(제톤 설명, 다른 도구의 응답, 사용자 메시지)에 넘어갈 수 있습니다. 예를 들어 TON Foundation의 공식 @ton/mcp가 이런 구조입니다. operator 키를 가진 에이전트 지갑으로서 전송과 스왑을 스스로 서명합니다(split-key 방식: operator 키는 에이전트가, owner 키는 사용자가 보유). 동작하는 모델이고 나름의 강점도 있습니다 — 자율적인 지출, NFT와 DNS 작업, 공식 패키지라는 지위. 하지만 이것은 결국 키 보유자에 대한 신뢰입니다.
  • 논커스터디얼 모델. 서버는 트랜잭션을 준비하기만 하고 서명되지 않은 상태로 반환합니다. 서명은 사용자 지갑이 TonConnect를 통해 수행합니다. 서버는 개인키를 보지도, 보관하지도 않습니다.

24시간 돌아가는 트레이딩 에이전트에게 두 번째 모델은 가장 큰 리스크를 없애줍니다. 인프라가 침해당하더라도 "망가지는" 것은 기껏해야 서명되지 않은 초안 하나이며, 그것은 어차피 여러분이 직접 또는 자기 지갑의 정책에 따라 승인해야 하는 것입니다. 이 갈림길에 대한 더 자세한 분석은 TONNode와 공식 @ton/mcp의 솔직한 비교에 정리해 두었습니다.

TONNode의 논커스터디얼 모델: 서버는 서명되지 않은 트랜잭션을 반환합니다

TONNode는 TON을 위한 hosted MCP 서버입니다. MCP(Model Context Protocol)는 AI 에이전트(Claude, Cursor, ChatGPT/Codex 및 모든 MCP 클라이언트)가 외부 도구를 호출하는 표준입니다. TONNode는 에이전트에게 TON을 다루는 도구 16개를 제공하며, 스왑, 크로스체인, 지갑 생성 도구는 엄격하게 논커스터디얼입니다.

핵심 불변식은 이것입니다. 서버는 절대로 서명하지 않으며 자금과 개인키를 보관하지 않습니다. 스왑에서 이는 최종 도구가 "체결된 거래"가 아니라 서명되지 않은 TonConnect 메시지, 즉 서명만 하면 되는 객체를 반환한다는 뜻입니다. 서버에는 서명이 없으므로, 서명 이후에 서버가 자금 수취인을 바꿔치기하는 것은 물리적으로 불가능합니다.

TONNode의 스왑은 정확히 두 개의 도구로 이루어집니다.

  • get_swap_quote — 확정 견적,
  • build_swap_tx — TonConnect에 바로 넘길 수 있는 서명되지 않은 트랜잭션.

둘 다 Omniston 프로토콜을 통해 동작합니다. Omniston은 STON.fi와 DeDust의 유동성을 동시에 집계하므로 견적은 두 DEX 모두에서 계산되고, 그중 더 나은 쪽을 받게 됩니다. 스왑은 GRAM⇄제톤 페어로 이루어집니다. GRAM은 이름이 바뀐 Toncoin입니다(2026년 6월 변경). 네트워크 자체는 여전히 TON이라고 부릅니다. 즉 견적에 나오는 "GRAM"은 이 네트워크의 네이티브 코인입니다.

get_swap_quote: Omniston(STON.fi + DeDust)을 통한 확정 견적

첫 단계는 실제로 얼마를 받게 되는지 확인하는 것입니다. get_swap_quote는 확정 견적, 즉 예상 수령액과 환율을 반환합니다. 내부적으로 Omniston이 STON.fi와 DeDust에 동시에 질의하기 때문에, 에이전트가 직접 풀을 돌아다니며 수동으로 비교할 필요가 없습니다. 이미 집계된 결과를 보게 됩니다.

100 USDT → GRAM 스왑 견적을 가져오세요.
get_swap_quote를 사용하세요. 예상 수령액과 환율을 보여주세요.

견적을 흔히 잘못 계산하게 만드는 중요한 지점이 하나 있습니다. 견적은 "사람이 읽는" 숫자가 아니라 raw 단위(토큰의 최소 분할 불가 단위)로 동작합니다. 그래서 제톤의 스왑 금액을 계산하기 전에 그 decimals를 알아야 합니다.

get_jetton_info: 스왑 전에 decimals가 필요한 이유 (USDT = 6)

스왑을 망가뜨리는 전형적인 실수는 이렇습니다. 에이전트가 "100 USDT"를 받아 금액 필드에 100을 넣습니다. 하지만 온체인에서 제톤에는 "100"이라는 개념이 없고 raw 단위만 존재합니다. 토큰 하나에 raw 단위가 몇 개 들어가는지는 decimals 파라미터가 정하며, 금액은 수량 × 10^decimals로 계산됩니다.

  • TON의 USDTdecimals = 6 → 100 USDT는 100 × 10^6 = 100 000 000 raw 단위입니다.
  • 대부분의 제톤decimals = 9 → 100 토큰은 100 000 000 000 raw 단위입니다.

(GRAM처럼) "100 USDT"에 0을 아홉 개 그냥 붙여 버리면 의도한 것보다 1000배 큰 금액의 스왑을 요청하게 됩니다. 여기서 자릿수를 세 개나 틀리기는 아주 쉽습니다. 그래서 get_jetton_info는 필수 단계입니다. 이 도구는 제톤의 이름, 심볼, decimals, 발행량을 반환합니다.

스왑 전에 get_jetton_info로 입력 제톤의 decimals를 확인하고,
그다음에 raw 단위로 금액을 계산하세요.

이 주제는 MCP로 AI 에이전트를 TON에 연결하기 글에서 더 깊이 다룹니다.

보조 도구: parse_address와 get_jetton_balance

트랜잭션을 조립하기 전에 호출해 두면 좋은 보조 도구 두 개도 있습니다.

  • parse_address — 주소(EQ/UQ/raw)의 오프라인 검증 및 변환. 무언가를 조립하기 전에 제톤 주소나 수취인 주소의 오타를 막아주는 값싼 보험입니다.
  • get_jetton_balance — 지갑 메인 주소 기준의 제톤 잔액. 잔액 조회에 쓰이는 제톤 지갑 주소는 도구 내부에서 온체인으로 계산되므로, 제톤 지갑 주소가 아니라 메인 주소를 넘겨야 합니다. 제톤 지갑 주소를 넣는 것이 흔한 실수입니다. 그럴 필요 없이 메인 주소를 주면 됩니다.

build_swap_tx: TonConnect용 서명되지 않은 메시지

견적을 받고 금액을 올바른 raw 단위로 계산했다면, build_swap_tx가 트랜잭션 자체를 조립합니다. 그리고 여기에 논커스터디얼의 본질이 있습니다. 이 도구는 서명되지 않은 TonConnect 메시지를 반환합니다. 이미 전송된 거래가 아니라 초안입니다. 컨트랙트 주소, 금액, payload가 들어 있습니다. 서버는 "봉투"를 건네주었을 뿐 봉인하지는 않았습니다. 봉인(서명)은 여러분의 지갑이 합니다.

그다음 이 메시지는 TonConnect 호환 지갑(Tonkeeper 등)으로 전달되고, 사용자는 자신이 정확히 무엇에 서명하는지 확인한 뒤 승인합니다. 개인키는 어느 단계에서도 지갑을 벗어나지 않으며 TONNode 서버로 넘어가지 않습니다.

마지막 견적을 기준으로 build_swap_tx로 스왑 트랜잭션을 조립하세요.
서명되지 않은 TonConnect 메시지를 반환하세요 — 서명은 제가 지갑에서 하겠습니다.

전체 흐름: 견적부터 지갑 서명까지

제톤 스왑의 전형적인 순서는 다음과 같습니다.

  1. parse_address — 제톤 주소와 수취인 주소를 검증하고 정규화합니다(오프라인).
  2. get_jetton_infodecimals(USDT는 6, 대개는 9), 이름, 심볼을 확인합니다.
  3. get_jetton_balance — 자금이 충분한지 확인합니다(제톤 지갑이 아니라 메인 주소).
  4. get_swap_quote — Omniston(STON.fi + DeDust)을 통해 확정 견적을 받습니다.
  5. build_swap_tx — 서명되지 않은 TonConnect 트랜잭션을 조립합니다.
  6. 사용자 지갑이 TonConnect로 서명합니다 — 서명은 사용자 쪽에서 이루어집니다.

프롬프트 수준에서 에이전트에게는 이렇게 자연스럽게 말하면 됩니다.

50 GRAM을 USDT로 교환하고 싶습니다.
먼저 parse_address로 USDT 제톤 주소를 확인하고,
get_jetton_info로 decimals를 확인하고,
get_jetton_balance로 잔액을 확인한 다음,
get_swap_quote로 견적을 받아 build_swap_tx로 트랜잭션을 조립하세요.
트랜잭션은 전송하지 마세요 — TonConnect용 서명되지 않은 메시지를 저에게 반환하세요.

에이전트가 이를 알아서 도구 호출로 분해해 주고, 최종적으로 여러분은 자기 지갑에서 서명할 초안을 받게 됩니다. 한 가지 유의할 점은 마지막 단계가 TONNode의 도구가 아니라는 것입니다. 서명은 지갑이 수행하며, 바로 이 지점이 논커스터디얼의 경계선입니다. 본격적인 트레이딩 에이전트를 만든다면 TON 트레이딩의 지연 분석을 살펴보세요. 거기서는 이 흐름이 의사결정 루프 안에 들어가 있습니다. 그리고 TON 바깥의 거래를 위해 TONNode에는 원자적 HTLC 에스크로 기반의 논커스터디얼 크로스체인 도구 5개가 있습니다.

스왑 도구를 Claude, Cursor, ChatGPT에 연결하는 방법

스왑 도구는 무료 Hobby를 포함한 모든 요금제에서 사용할 수 있습니다(Hobby는 60 요청/분). Hobby도 hosted 키입니다. 요금은 처리량에 대해서만 지불하며, 16개 도구 세트는 모든 키에서 동일합니다.

로컬 무료 — 읽기용. @tonnode/mcp 패키지는 오픈소스(MIT)이며, HTTP 중간 계층 없이 TON의 네이티브 ADNL 프로토콜로 동작하고 명령 한 줄로 실행됩니다. 공개 설정만으로 읽기 도구 전체를 사용할 수 있습니다.

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

Hosted 엔드포인트 — 스왑과 나머지 전부. 자신의 키(무료 Hobby로 충분), 보장된 처리량, 그리고 get_swap_quotebuild_swap_tx를 포함한 16개 도구 전부를 제공합니다.

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

이 설정은 사용하는 클라이언트의 MCP 설정에 넣습니다 — Claude Desktop, Cursor, ChatGPT/Codex 또는 그 밖의 모든 MCP 호환 에이전트. hosted 키를 연결하면 get_swap_quotebuild_swap_tx 도구가 에이전트에 자동으로 나타납니다. tn_live_… 키는 로그인 직후 카드 없이 발급됩니다.

핵심 요약

  • TONNode의 스왑은 두 개의 도구입니다. get_swap_quote(확정 견적)와 build_swap_tx(TonConnect용 서명되지 않은 트랜잭션).
  • 둘 다 STON.fi와 DeDust의 유동성 집계자인 Omniston을 통해 동작합니다.
  • 서명은 언제나 사용자에게 있습니다. 서버는 키를 보관하지도 서명하지도 않습니다 — 커스터디얼 방식인 공식 @ton/mcp와 다른 점입니다.
  • 제톤을 스왑하기 전에 get_jetton_infodecimals를 확인하세요(USDT = 6, 대부분 = 9). 그러지 않으면 raw 단위 금액이 잘못 계산됩니다.
  • 스왑 도구는 무료 Hobby를 포함한 모든 hosted 키에서 동작합니다.

에이전트를 위한 TON 논커스터디얼 스왑은 결국 역할 분리의 규율입니다. 서버는 계산하고 조립하며, 지갑은 서명합니다. TONNode에서 이것은 Omniston 위에 얹힌 정확히 두 개의 도구, 그리고 정확한 decimals를 위한 get_jetton_info로 구현되며, 어떤 개인키도 사용자 곁을 떠나지 않습니다.

가장 쉬운 시작은 무료 키입니다. 카드 없이 Hobby 키를 받아 몇 분 만에 스왑 도구를 연결하세요: tonnode.io/dashboard?plan=hobby. 도구 전체를 먼저 살펴보고 싶다면 도구 페이지를 확인하세요.

에이전트에게 TON 접근 권한을 주세요

16가지 MCP 도구: 읽기, 논커스터디얼 스왑, 크로스체인, 지갑. 무료 요금제 60 요청/분, 카드 불필요.