# 기본 실습 명령

## 팀 설정과 연결

주최자가 등록을 마친 팀 설정을 `team.config.json`으로 제공해야 해요. 예시 파일의 NOT_CONFIGURED는 실제 계정이 아니에요. 팀마다 별도 부모 지갑을 사용하세요. 처음부터 마지막까지 같은 터미널의 환경 변수와 `.local`을 유지하세요.

```sh
export POUCHI_CONFIG="$PWD/team.config.json"
npm ci
npm run doctor -- --network
npm run setup -- --link-only
```

setup이 반환한 승인 링크에서 소유자가 이메일 인증, 본인의 PIN 설정과 연결 승인을 완료하세요. 이미 지갑이 있으면 해당 로그인 경로를 사용하세요. PIN이나 인증 코드를 에이전트·채팅에 전달하지 마세요. 이 사람 승인 단계는 운영자가 사전 완료 검증해야 해요.

```sh
npm run setup -- --json
npm run setup -- --status
npm run mcp:config
node examples/call.mjs --list
node examples/call.mjs wallet_status '{"name":"my-agent"}'
```

setup은 최대 5분 기다리며 `--wait-seconds 60`으로 줄일 수 있어요. 시간 초과는 연결 성공이 아니에요. 같은 상태 경로에서 다시 실행하거나 `--status`로 확인하세요. 토큰을 직접 주입하지 마세요. `mcp:config`가 출력하는 설정을 에이전트 클라이언트에 등록하면 같은 도구를 사용할 수 있어요.

각 실행의 `operation_status`가 `succeeded`이고 실제 transactionHash가 있어야 다음 단계로 진행하세요. `pending`·`execution_pending`·`outcome_unknown`이면 여기서 멈추고 원래 ID만 조회하세요. 아래 명령 블록은 성공 확인을 대신하지 않아요.

## 생성과 충전

아래 requestId는 새 실습용이에요. 이미 사용한 ID의 내용은 바꾸지 마세요. 각 요청의 실제 응답에서 policyId를 복사하세요. 예시 `<실제 policyId>`는 실행 전에 교체해야 해요.

```sh
node examples/call.mjs wallet_request '{"name":"my-agent","action":"create","requestId":"create-demo-001"}'
node examples/call.mjs operation_status '{"requestId":"create-demo-001"}'
```

응답의 approvalUrl에서 소유자가 승인하세요. operation_status의 policyState가 enabled인 것을 확인한 뒤 실행하세요.

```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 생성 policyId>","requestId":"exec-create-001"}'
node examples/call.mjs operation_status '{"requestId":"exec-create-001"}'
node examples/call.mjs wallet_request '{"name":"my-agent","action":"fund","amountOkrw":"0.3","requestId":"fund-demo-001"}'
```

충전도 소유자 승인과 enabled 확인 후 실행하세요.

```sh
node examples/call.mjs operation_status '{"requestId":"fund-demo-001"}'
```
 부모 지갑에 최소 0.3 테스트 OKRW가 있어야 하고, 별도의 주최자 가스 스폰서도 필요해요. 부족하면 반복 제출하지 말고 주최자에게 요청하세요.

```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 충전 policyId>","requestId":"exec-fund-001"}'
node examples/call.mjs operation_status '{"requestId":"exec-fund-001"}'
node examples/call.mjs wallet_status '{"name":"my-agent"}'
```

## 지출과 재시도

주최자가 지정한 테스트 수신자로 교체하세요. 기본판은 회당 0.1 테스트 OKRW, 최대 2회, 1시간, 빈 calldata를 고정하는 정책이에요. 임의 계약 호출·범용 예산·외부 서비스 구매 기능을 뜻하지 않아요.

```sh
node examples/call.mjs policy_request '{"name":"my-agent","purpose":"작업 완료 보상","recipient":"<주최자가 지정한 수신자 주소>","maxCalls":2,"requestId":"spend-policy-001"}'
```

approvalUrl에서 소유자가 승인하고 policyState enabled를 확인한 뒤 실행하세요.

```sh
node examples/call.mjs operation_status '{"requestId":"spend-policy-001"}'
```


```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 지출 policyId>","requestId":"exec-spend-001"}'
node examples/call.mjs operation_status '{"requestId":"exec-spend-001"}'
node examples/call.mjs wallet_execute '{"policyId":"<실제 지출 policyId>","requestId":"exec-spend-001"}'
node examples/call.mjs wallet_status '{"name":"my-agent"}'
```

같은 requestId의 재호출은 동일 거래로 조회돼야 하고 추가 송금이 생기면 안 돼요. 이 기본 실습에서 1회 지출 후 자식 잔액은 0.2예요. 미확정·응답 유실이면 원래 requestId로 operation_status를 호출하세요. 새 ID로 바꾸어 다시 보내지 마세요.

## 동결과 회수

```sh
node examples/call.mjs wallet_request '{"name":"my-agent","action":"freeze","requestId":"freeze-demo-001"}'
```

소유자 승인 후 다음 조회에서 enabled를 확인하세요.

```sh
node examples/call.mjs operation_status '{"requestId":"freeze-demo-001"}'
```

```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 동결 policyId>","requestId":"exec-freeze-001"}'
node examples/call.mjs operation_status '{"requestId":"exec-freeze-001"}'
node examples/call.mjs wallet_status '{"name":"my-agent"}'
```

동결 실행 succeeded와 wallet_status의 frozen:true를 확인한 뒤에만 아래 차단 테스트를 실행하세요.

```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 지출 policyId>","requestId":"blocked-spend-001"}'
```

마지막 요청은 AGENT_WALLET_FROZEN으로 차단돼야 해요. 차단이 확인되지 않으면 주최자에게 원래 ID를 전달하고 멈추세요.

```sh
node examples/call.mjs wallet_request '{"name":"my-agent","action":"recover","amountOkrw":"0.2","requestId":"recover-demo-001"}'
```

소유자 승인 후 다음 조회에서 enabled를 확인하세요. 회수는 소유자 부모 지갑으로만 가능해요.

```sh
node examples/call.mjs operation_status '{"requestId":"recover-demo-001"}'
```

```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 회수 policyId>","requestId":"exec-recover-001"}'
node examples/call.mjs operation_status '{"requestId":"exec-recover-001"}'
node examples/call.mjs wallet_status '{"name":"my-agent"}'
```

## 철회와 결과

```sh
node examples/call.mjs policy_revoke '{"policyId":"<실제 지출 policyId>","requestId":"revoke-demo-001"}'
node examples/call.mjs operation_status '{"requestId":"revoke-demo-001"}'
```

철회도 응답의 approvalUrl에서 소유자가 승인해야 해요. revoked 상태를 확인한 뒤 새 실행이 BUDGET_REVOKED로 차단되는지 확인하세요.

```sh
node examples/call.mjs wallet_execute '{"policyId":"<실제 지출 policyId>","requestId":"blocked-spend-002"}'
```

최종 자식 잔액은 0, 동결 상태, 지출 정책은 철회 상태가 기본 실습 결과예요. 거래는 succeeded와 실제 transactionHash를 확인하세요. RPC 오류는 성공으로 바꾸지 마세요. `.local`에는 키·연결 상태가 있으므로 제출하지 마세요. 제출 양식에는 공개 주소·거래 해시·차단 코드만 옮기세요.
