스크립트 실행 명령어
$npx ts-node xrpl/Wallet/LoadWallet.ts
$npx ts-node xrpl/Wallet/faucet.ts
$npx ts-node xrpl/Wallet/WalletInfo.ts
$npx ts-node xrpl/Wallet/createNewWallet.ts
Bash
복사
1. Wallet
Wallet은 XRPL 계정을 생성/로드/펀딩/조회하기 위한 도구(스크립트 모음)이다.
•
생성: 새 주소/시드 발급
•
펀딩(Devnet): Faucet으로 활성화(기본 리저브 충족)
•
조회: 잔액, 시퀀스, Flags, TrustLines 등
2. 왜 필요한가?
•
개발 초기 세팅: 테스트 계정 빠르게 준비
•
자동화: 반복 테스트에서 계정 생성/펀딩/조회 스크립트 표준화
•
디버깅: 실패 원인 분석 시 계정 상태 쉽게 확인
3. 시나리오: generate → faucet → get-wallet-info
Step 1. 새 지갑 생성 (createNewWallet.ts)
•
주체: 개발자
•
행동: 새 시드/주소 생성
•
내용: 콘솔에 address/seed 출력
import dotenv from 'dotenv'
import path from 'path'
import { Wallet } from 'xrpl'
// .env 파일 로드 (이 스크립트에서는 직접 사용하지 않지만, 프로젝트 전체 일관성을 위해 포함)
dotenv.config({ path: path.join(__dirname, '..', '.env') })
export async function createNewWallet() {
try {
// 1. 새 지갑 생성 — 랜덤하게 키쌍, 주소, 시드가 생성됨
const newWallet = Wallet.generate()
// 2. 콘솔 출력 — 생성된 지갑의 기본 정보 확인 가능
// ⚠️ 시드(seed)는 계정 권한 전체를 의미하므로 반드시 안전하게 보관 필요
console.log('새 지갑 생성 완료')
console.log(`주소: ${newWallet.address}`) // r로 시작하는 XRPL 주소
console.log(`시드: ${newWallet.seed}`) // s로 시작하는 XRPL 시드
console.log(`공개키: ${newWallet.publicKey}`) // 33바이트 hex 형식 공개키
// 3. 함수 반환 — 다른 스크립트에서 불러 쓸 수 있도록 객체 형태로 반환
return {
wallet: newWallet,
address: newWallet.address,
seed: newWallet.seed!
}
} catch (error) {
// 예외 처리 — Wallet.generate() 자체는 거의 실패하지 않지만 런타임 예외 대비
console.error('❌ 새 지갑 생성 실패:', error)
throw new Error(`새 지갑 생성 실패: ${error}`)
}
}
// 모듈이 직접 실행된 경우에만 createNewWallet 실행
// (다른 곳에서 import할 경우에는 함수만 제공)
if (require.main === module) {
createNewWallet()
}
TypeScript
복사
Step 2. Devnet 펀딩 (faucet.ts)
•
주체: 개발자
•
행동: Devnet Faucet으로 해당 시드 지갑 활성화
•
내용: 리저브/수수료 지불 가능한 최소 잔액 확보
import dotenv from "dotenv"
import path from "path"
import { Client, Wallet } from "xrpl"
// .env 파일 로드 (시드값을 환경변수에서 불러오기 위함)
dotenv.config({ path: path.join(__dirname, "..", ".env") })
export async function faucetAll() {
// XRPL Devnet에 연결 (테스트용 네트워크)
const client = new Client("wss://s.devnet.rippletest.net:51233")
await client.connect()
try {
// 1. Admin 계정 활성화
if (process.env.ADMIN_SEED) {
const adminWallet = Wallet.fromSeed(process.env.ADMIN_SEED.trim())
// faucet으로 지정된 지갑에 테스트 XRP 지급 (리저브 충족 및 트랜잭션 가능 상태로 만듦)
await client.fundWallet(adminWallet)
console.log(`✅ ADMIN (${adminWallet.address}) 계정 활성화 완료`)
} else {
console.warn("⚠️ ADMIN_SEED 환경변수 없음")
}
// 2. User 계정 활성화
if (process.env.USER_SEED) {
const userWallet = Wallet.fromSeed(process.env.USER_SEED.trim())
await client.fundWallet(userWallet)
console.log(`✅ USER (${userWallet.address}) 계정 활성화 완료`)
} else {
console.warn("⚠️ USER_SEED 환경변수 없음")
}
// 3. User2 계정 활성화
if (process.env.USER2_SEED) {
const user2Wallet = Wallet.fromSeed(process.env.USER2_SEED.trim())
await client.fundWallet(user2Wallet)
console.log(`✅ USER2 (${user2Wallet.address}) 계정 활성화 완료`)
} else {
console.warn("⚠️ USER2_SEED 환경변수 없음")
}
} catch (err) {
// faucet 호출 실패 시 오류 출력
console.error("❌ 계정 활성화 중 오류:", err)
} finally {
// 항상 연결 종료
await client.disconnect()
console.log("🔄 연결 종료")
}
}
// 직접 실행된 경우에만 faucetAll 실행
if (require.main === module) {
faucetAll()
}
TypeScript
복사
Step 3. 지갑 정보 조회 (WalletInfo.ts)
•
주체: 누구나
•
행동: account_info, account_lines 등으로 상태 조회
•
내용: XRP 잔액, Sequence, Flags, TrustLines, RegularKey 등
import dotenv from "dotenv"
import path from "path"
import { Client, Wallet } from "xrpl"
// .env 파일 로드 (시드값 불러오기 위함)
dotenv.config({ path: path.join(__dirname, "..", ".env") })
export async function WalletInfo() {
// XRPL Devnet 노드에 연결
const client = new Client("wss://s.devnet.rippletest.net:51233")
await client.connect()
try {
// 환경변수에서 시드값 로드
const adminSeed = process.env.ADMIN_SEED
const userSeed = process.env.USER_SEED
const user2Seed = process.env.USER2_SEED
if (!adminSeed || !userSeed || !user2Seed) {
throw new Error("환경변수 ADMIN_SEED, USER_SEED, USER2_SEED 모두 필요")
}
// Seed로 Wallet 객체 생성
const adminWallet = Wallet.fromSeed(adminSeed.trim())
const userWallet = Wallet.fromSeed(userSeed.trim())
const user2Wallet = Wallet.fromSeed(user2Seed.trim())
// 1) 각 계정의 XRP 잔액 조회
const adminBalance = await client.getXrpBalance(adminWallet.address)
const userBalance = await client.getXrpBalance(userWallet.address)
const user2Balance = await client.getXrpBalance(user2Wallet.address)
// 2) 각 계정의 Account Info 조회 (시퀀스, Flags, RegularKey 등)
const adminInfo = await client.request({ command: "account_info", account: adminWallet.address })
const userInfo = await client.request({ command: "account_info", account: userWallet.address })
const user2Info = await client.request({ command: "account_info", account: user2Wallet.address })
// 3) 각 계정의 TrustLine 목록 조회
const adminLines = await client.request({ command: "account_lines", account: adminWallet.address })
const userLines = await client.request({ command: "account_lines", account: userWallet.address })
const user2Lines = await client.request({ command: "account_lines", account: user2Wallet.address })
// 결과 출력
console.log("📌 지갑 정보")
console.log(
`ADMIN: ${adminWallet.address} | Balance: ${adminBalance} XRP | Sequence: ${adminInfo.result.account_data.Sequence} | Flags: ${adminInfo.result.account_data.Flags} | RegularKey: ${adminInfo.result.account_data.RegularKey ?? "없음"}`
)
console.log(
`USER: ${userWallet.address} | Balance: ${userBalance} XRP | Sequence: ${userInfo.result.account_data.Sequence} | Flags: ${userInfo.result.account_data.Flags} | RegularKey: ${userInfo.result.account_data.RegularKey ?? "없음"}`
)
console.log(
`USER2: ${user2Wallet.address} | Balance: ${user2Balance} XRP | Sequence: ${user2Info.result.account_data.Sequence} | Flags: ${user2Info.result.account_data.Flags} | RegularKey: ${user2Info.result.account_data.RegularKey ?? "없음"}`
)
console.log(
`TrustLines - ADMIN: ${adminLines.result.lines.length}, USER: ${userLines.result.lines.length}, USER2: ${user2Lines.result.lines.length}`
)
} catch (error) {
// 오류 발생 시 로그 출력
console.error("❌ 지갑 정보 조회 실패:", error)
} finally {
// 연결 종료
await client.disconnect()
console.log("🔄 연결 종료")
}
}
// 직접 실행된 경우 WalletInfo 실행
if (require.main === module) {
WalletInfo()
}
TypeScript
복사

