Skip to content

Quickstart ​

다음 순서로 Wallet API 핵심 연동을 확인합니다. 먼저 Node.js, curl, openssl, jq를 준비하고 발급받은 연동 정보를 환경 변수로 설정합니다.

bash
export WALLET_BASE_URL='https://{environment-api-host}'
export WALLET_API_KEY='{issued-api-key}'
export WALLET_HMAC_KEY='{issued-hmac-key}'

wallet_request ​

wallet_request는 Wallet API 호출을 위해 정의하는 셸 함수입니다. 호출 형식은 wallet_request <HTTP 메서드> <Base URL을 제외한 경로와 쿼리> [JSON 본문]입니다. 아래 코드 블록 전체를 환경 변수를 설정한 현재 셸에서 실행합니다. 새 셸을 열면 환경 변수 설정과 함수 등록을 다시 진행합니다.

이 함수는 요청마다 timestamp와 nonce를 새로 만들고, 실제로 전송할 경로와 body를 HMAC-SHA256으로 서명합니다.

bash
wallet_request() {
  local method="$1"
  local request_path="$2"
  local body="${3-}"
  local timestamp nonce signature
  timestamp="$(node -e 'process.stdout.write(String(Date.now()))')"
  nonce="$(node -e 'process.stdout.write(require("crypto").randomUUID())')"
  signature="$(printf '%s\n\n%s\n\n%s\n\n%s\n\n%s' \
    "$method" "$request_path" "$timestamp" "$nonce" "$body" \
    | openssl dgst -sha256 -hmac "$WALLET_HMAC_KEY" -binary \
    | openssl base64 -A)"

  if [ -n "$body" ]; then
    curl -sS -X "$method" "$WALLET_BASE_URL$request_path" \
      -H "X-API-KEY: $WALLET_API_KEY" \
      -H "X-TIMESTAMP: $timestamp" \
      -H "X-NONCE: $nonce" \
      -H "X-SIGNATURE: $signature" \
      -H 'Content-Type: application/json' \
      --data-raw "$body"
  else
    curl -sS -X "$method" "$WALLET_BASE_URL$request_path" \
      -H "X-API-KEY: $WALLET_API_KEY" \
      -H "X-TIMESTAMP: $timestamp" \
      -H "X-NONCE: $nonce" \
      -H "X-SIGNATURE: $signature"
  fi
}

이 helper는 Quickstart 실행용입니다. 운영 코드에는 timeout, 응답 검증과 제한된 재시도 정책을 추가하고, 정확한 서명 규칙은 HMAC 요청 서명을 확인하십시오.

1. 기준정보 조회 ​

이 예제는 Ethereum Sepolia 테스트넷을 사용합니다. 메인넷·테스트넷 구분과 주요 목록은 지원 네트워크에서 확인합니다.

bash
usdt_response="$(wallet_request GET '/asset-types?code=USDT&page=1&page_size=20')"
sepolia_response="$(wallet_request GET '/networks?is_active=true&page=1&page_size=100')"
printf '%s\n' "$usdt_response" | jq
printf '%s\n' "$sepolia_response" | jq

export ASSET_TYPE_ID="$(printf '%s' "$usdt_response" | jq -er '.data.items[0].id // empty')"
export NETWORK_ID="$(printf '%s' "$sepolia_response" | jq -er '.data.items[] | select(.chain_id == 11155111) | .network_id')"

wallet_request GET "/assets/by-type-network?asset_type_id=$ASSET_TYPE_ID&network_id=$NETWORK_ID" | jq

success: true인지 확인하고 조회된 자산이 USDT, 네트워크가 Ethereum Sepolia인지 확인합니다. Sepolia는 chain_id: 11155111로 찾습니다. 조회 결과에 없으면 다음 페이지와 대상 환경의 지원 여부를 확인하고 진행을 중단합니다. 자산·네트워크 조합의 data.is_active도 true여야 합니다.

각 단계에서 응답이 실패하거나 ID가 비어 있으면 다음 요청을 실행하지 마십시오. 예제의 curl -sS는 HTTP 오류에도 JSON을 출력할 수 있으며, | jq는 응답 표시용입니다. HTTP 상태와 success를 함께 확인하고 null을 ID로 사용하지 않습니다.

2. 고객 계정 생성 또는 재사용 ​

POST /accounts는 멱등 API가 아니므로 먼저 /users/{uid}/accounts를 조회합니다. 의도한 계정이 없을 때만 USER 계정을 만들고 account_id를 저장합니다.

bash
export CUSTOMER_UID='user-tutorial-001'
wallet_request GET "/users/$CUSTOMER_UID/accounts" | jq

의도한 활성 USER 계정이 있으면 반환된 account_id를 설정하고 생성 코드는 건너뜁니다. 여러 계정이 있으면 고객사에 저장된 연결 정보를 기준으로 선택합니다.

bash
export ACCOUNT_ID='{existing-active-user-account-id}'

계정이 없는 경우에만 다음 코드를 실행합니다.

bash
account_body="$(jq -nc --arg uid "$CUSTOMER_UID" \
  '{uid:$uid,account_type:"USER",metadata:{source:"quickstart"}}')"
account_response="$(wallet_request POST '/accounts' "$account_body")"
printf '%s\n' "$account_response" | jq
export ACCOUNT_ID="$(printf '%s' "$account_response" | jq -er '.data.account_id // empty')"

GET /accounts/{account_id}로 uid, account_type: USER, status: ACTIVE를 확인하고 고객과 계정의 연결을 저장합니다. 생성 응답이 유실되면 같은 uid의 계정 목록을 먼저 확인합니다.

3. 입금 주소 발급 ​

POST /accounts/{account_id}/deposit-addresses에 숫자형 asset_type_id와 network_id를 전달합니다. 반환된 주소, 네트워크, tag_or_memo를 함께 저장합니다.

bash
address_body="{\"asset_type_id\":$ASSET_TYPE_ID,\"network_id\":$NETWORK_ID}"
address_response="$(wallet_request POST "/accounts/$ACCOUNT_ID/deposit-addresses" "$address_body")"
printf '%s\n' "$address_response" | jq

4. 지갑 확인 ​

bash
wallet_request GET "/accounts/$ACCOUNT_ID" | jq
wallet_request GET "/accounts/$ACCOUNT_ID/balances" | jq

입출금은 Wallet 튜토리얼, 고객-가맹점 결제는 Digital Payment 튜토리얼에서 이어서 진행합니다.

완료 기준 ​

다음 조건을 만족하면 Quickstart가 완료된 것입니다.

  • Provisioning을 반복해도 중복 계정이 아니라 의도한 기존 계정을 재사용합니다.
  • 저장한 입금 목적지에 네트워크와 memo 정보가 함께 있습니다.
  • 잔액 금액을 문자열 또는 decimal-safe 값으로 유지합니다.
  • 실패 응답의 upstream request_id를 보존합니다.
  • 읽기 단계를 다시 실행해도 안전합니다.

Quickstart에서는 실제 자산을 전송하지 않습니다. 테스트 네트워크를 사용하고 faucet이나 테스트 token을 요청하기 전에 선택한 자산 배포가 활성 상태인지 확인합니다.

OOLIN은 BPMG가 제공하는 디지털자산 운영 인프라 제품입니다.