개발자 문서

퀵스타트

이것은 아무것도 없는 상태에서 자율 결제를 할 수 있는 에이전트까지 이르는, 가장 짧은 실제 경로입니다. Tidal의 승인된 개발자 플랫폼 및 SDK 계약에 근거합니다. 플랫폼이 아직 만들어지는 중이므로 일부 세부 사항은 초안 — 확정 예정으로 표시했습니다. 구조는 정확하지만, 버전 번호와 제공 여부, 그리고 정확한 와이어 세부 사항은 SDK가 출시되기 전까지 잠정적인 것으로 봐 주세요.

초안 — 확정 예정. 아래의 SDK 패키지, 진입점, 초기화 및 결제 표면은 승인된 계약에서 직접 가져온 것입니다. 아직 공개적으로 승인된 호스팅 스테이징 대상이 없으며, 결제 표면의 일부는 현재 더 작은 구성 요소로 출시됩니다(5단계 참고). 샌드박스 / 테스트넷에서 시작하세요. 메인넷은 별도의 검토 뒤에 열립니다.

시작하기 전에

이 모든 것은 서버 측 백엔드에서 합니다. Tidal 에이전트 SDK의 서명·자격 증명 표면은 의도적으로 서버 전용입니다. 브라우저, 확장 프로그램, React Native 번들에 결코 들어가서는 안 됩니다. Node.js가 필요하며, 로컬 개발을 넘어서는 모든 것에는 에이전트의 개인키를 쥘 클라우드 키 저장소(AWS KMS 또는 GCP KMS)가 필요합니다.

1. 개발자 계정과 자격 증명 만들기

Tidal 개발자 포털(portal.t54.ai)에서 개발자 조직과 애플리케이션 클라이언트를 온보딩하고, 샌드박스 환경을 위한 환경별 API 자격 증명을 만듭니다. 샌드박스와 메인넷은 별개의 보안 도메인입니다. 자격 증명, 에이전트 키, 도메인 바인딩은 둘 사이에서 결코 공유되지 않습니다.

자격 증명에는 세 부분이 있으며, 그 구분이 중요합니다.

  • apiKey — 애플리케이션의 공개 식별자(접두사 t54_pk_). 앱을 식별할 뿐, 결코 사용자 동의를 증명하지 않으며 그 자체로 결제를 승인하지도 않습니다.
  • apiSecretEd25519 요청 서명 개인키(접두사 t54_sk_)이며, 베어러 토큰이 아닙니다. 당신의 백엔드가 로컬에서 생성하고, 포털은 공개 절반만 받습니다.
  • kid — 어느 키 버전이 요청에 서명하는지를 지칭하는 키 버전 식별자(접두사 t54_kid_).

apiSecret은 당신 쪽에 남는 서명 키이므로, 포털은 그것을 표시하거나 복구하거나 저장할 수 없습니다. 시크릿 매니저에 보관하세요. Tidal로 가는 모든 인증 요청은 그것으로 서명됩니다.

2. SDK 설치

npm install @xrpl-agent-wallet/agent-wallet-sdk

패키지는 런타임별로 구별된 진입점을 노출합니다. 당신은 server 진입점과 하나의 keystore 어댑터를 사용합니다.

진입점용도
@xrpl-agent-wallet/agent-wallet-sdk/server인증된 클라이언트: init, createAgent, 승인, 결제. 서버 전용.
@xrpl-agent-wallet/agent-wallet-sdk/keystore/aws-kmsAWS KMS의 에이전트 키(secp256k1). 프로덕션 사용 가능.
@xrpl-agent-wallet/agent-wallet-sdk/keystore/gcp-kmsGCP KMS의 에이전트 키(Ed25519). 승인된 라이브 벡터 전까지 fail-closed로 출시 — 참고 참조.
@xrpl-agent-wallet/agent-wallet-sdk/keystore/encrypted-file로컬 암호화 파일, 개발 전용, 메인넷 거부.
@xrpl-agent-wallet/agent-wallet-sdk/public브라우저/확장/RN 안전 타입과 링크 헬퍼. 비밀 없음.

초안 — 확정 예정. GCP(Ed25519) 어댑터는 명세되어 있지만, 라이브 혼합 알고리즘 테스트넷 서명 벡터가 독립적으로 승인되기 전까지 fail-closed로 출시됩니다. 첫 통합에는 로컬에서 encrypted-file을 사용하고 프로덕션에서는 aws-kms를 계획하세요.

3. 서버 SDK 초기화

초기화는 당신의 자격 증명을 로컬에서 검증하고, 서명된 챌린지로 앱과 환경 바인딩을 증명하며, 키 저장소의 능력을 동결합니다. 이 검사들이 통과하기 전에는 어떤 키 생성이나 결제 메서드도 노출하지 않습니다. 익명이나 저하 모드는 없습니다.

import { init } from "@xrpl-agent-wallet/agent-wallet-sdk/server";
import { encryptedFileKeyStore } from "@xrpl-agent-wallet/agent-wallet-sdk/keystore/encrypted-file";

const sdk = await init({
  apiKey: process.env.TIDAL_API_KEY!,       // t54_pk_...
  apiSecret: process.env.TIDAL_API_SECRET!, // t54_sk_... (로그에 남기지 않음)
  keyStore: encryptedFileKeyStore({ /* 개발 전용 설정 */ }),
  environment: "sandbox",
});

4. 에이전트 생성

createAgent당신의 불투명한 식별자 아래에 에이전트를 등록합니다. 키는 당신의 키 저장소에서 생성되고, 공개키와 불투명 참조만 Tidal에 도달합니다. 호출은 (조직, 앱, 환경, userId, agentId)에 대해 멱등합니다. 같은 튜플에 같은 공개키면 기존 레코드를 반환하고, 로컬 키 생성 후의 재시도는 새 키를 찍어내는 대신 같은 키를 재사용합니다.

const agent = await sdk.createAgent("user-42", "research-agent");
// agent.record 에 불변 디렉터리 레코드(공개키, XRPL 계좌, generation ...)가 담김

userIdagentId는 당신이 정하되 불투명해야 합니다. 이메일, 이름, 비밀 자료를 담지 마세요. 나중에 부수 효과 없이 기존 에이전트를 재개하려면 openAgent(userId, agentId)를 쓰며, 로컬 키 레코드와 Tidal 디렉터리 레코드가 정확히 일치하지 않으면 fail-closed로 실패합니다.

5. 승인 요청, 그리고 결제

앱은 사용자에게 한도 안에서 에이전트를 승인하도록 요청합니다. requestAuthorization은 공개 App Link / QR 페이로드 — 비밀은 결코 없는 라우팅 핸들 — 를 반환하고, 당신은 이를 사용자에게 제시합니다. 사용자는 자신의 Tidal 지갑에서 이를 승인하며, 예산 계좌에 자금을 넣고 준비합니다.

const authRequest = await agent.requestAuthorization({
  limits: { perPayment: "1", daily: "10", lifetime: "100" }, // 형태는 예시
  currency: "RLUSD",
  expiry: "2026-12-31T00:00:00Z",
});
// authRequest 의 링크/QR 을 사용자에게 제시. 승인 대기(폴링 또는 웹훅).

승인이 활성화되면 에이전트가 결제합니다. 모든 결제는 멱등합니다. 고유하고 엔트로피가 높은 idempotencyKey를 제공하며, SDK는 재시도 시 새 키를 슬그머니 찍어내지 않습니다.

const receipt = await agent.pay({
  destination: "rMerchantXRPLAddress...",
  amount: { currency: "RLUSD", value: "0.50" }, // 형태는 예시
  idempotencyKey: myUniqueKey,
});

내부적으로 pay()는 전체 수명주기를 돌립니다. 정책 결정을 받고, 정확히 동결된 거래에 대해 당신의 키 저장소가 에이전트 절반을 서명하게 하고, (승인 시에만 주어지는) Tidal의 공동서명을 요청하고, 2-of-2 결제를 조립하고, 한 번 제출하며, 최종성을 대사한 뒤 묶인 영수증을 반환합니다. 통합 가이드가 그 순서를 온전히 짚습니다.

초안 — 확정 예정. 단일 호출 agent.pay() 상태 기계가 목표 표면입니다. 현재 서버 SDK는 더 작은 검토된 구성 요소인 agent.initiatePayment(input)agent.getPayment(operationId)를 출시합니다. initiation은 결제 초기화 호출을 한 번 하고 내부적으로 재시도하지 않으며, read는 오퍼레이션을 폴링합니다. 챌린지가 필요하면 initiation이 challenge_pending 상태를 드러내고, 이를 해소한 뒤 이어갑니다. 오늘은 initiatePayment / getPayment 위에 구축하고, pay()가 나오면 채택하세요.

흔한 결과 다루기

결제는 fail-closed이며, SDK는 상태 코드에서 추측하는 대신 정확히 대응하도록 타입이 지정된 오류를 내보냅니다. 가장 먼저 마주칠 것들:

  • PolicyDeniedError — 결제가 한도나 정책 규칙을 어겼습니다. 서명되지 않았습니다.
  • ChallengePendingError — 정책이 사용자에게 챌린지 답을 요구합니다. 해소한 뒤 같은 오퍼레이션을 이어가세요.
  • InsufficientBudgetError — 예산 계좌가 예비금과 수수료 위로 이를 감당할 수 없습니다.
  • IdempotencyConflictError — 같은 멱등 키가 다른 요청으로 재사용되었습니다.
  • ReconciliationRequiredError — 제출이 모호했습니다. 재제출하지 말고 묶인 트랜잭션 ID로 대사하세요.

전체 목록과 HTTP 매핑은 통합 가이드에 있습니다.

다음으로 읽을거리

  • 개념 — 방금 사용한 객체와 권위체에 대한 설명.
  • 통합 가이드 — 결제 수명주기와 멱등성을 자세히.
  • 보안 모델 — 왜 키를 맡겨도 안전한가.