— TIMED ACCOUNT LENDING · BLOCK-TIME EXPIRY · INSTANT RECALL —
An account owner (lessor) can lend an account (Slot) to another user for a fixed period. The lease is recorded on-chain in the SlotLease contract and expires by block time. The A server moves sign-in rights to the account borrower (lessee) and takes them back when the lease ends. This page explains how the on-chain and off-chain parts work together and what your app sees. 계정 소유자(lessor)는 계정(Slot)을 다른 사용자에게 정해진 기간 동안 빌려줄 수 있습니다. 대여는 SlotLease 컨트랙트에 온체인으로 기록되고 블록 시각으로 만료됩니다. A 서버는 로그인 권한을 계정 대여자(lessee)에게 넘겼다가 대여가 끝나면 되돌립니다. 이 페이지는 온체인과 오프체인이 어떻게 맞물리는지, 그리고 앱에서 무엇이 보이는지 설명합니다.
A lease hands over sign-in rights only. Account (Slot) ownership on dex v2 (get_slot_owner) never changes. The person who lends is the account owner (lessor) and the person who borrows is the account borrower (lessee).
대여는 접속권(로그인 권한)만 위임합니다. dex v2 의 계정(Slot) 소유권(get_slot_owner)은 바뀌지 않습니다. 빌려주는 사람을 계정 소유자(lessor), 빌리는 사람을 계정 대여자(lessee)라고 부릅니다.
| Rule규칙 | Value값 |
|---|---|
| duration | Units minute, hour, day, month, year with a positive integer. Minimum 1 minute, maximum 5 years. Months and years are added on the UTC calendar, and a missing day snaps to the month end (Jan 31 + 1 month = Feb 28).단위 minute·hour·day·month·year 와 양의 정수. 최소 1분, 최대 5년. 개월·년은 UTC 달력으로 더하고, 없는 날짜는 그 달 말일로 맞춥니다(1/31 + 1개월 = 2/28). |
| offer | Valid for 72 hours. The account borrower must accept. Leases are free only.72시간 유효. 계정 대여자가 수락해야 시작됩니다. 무료 대여만 지원합니다. |
| eligible account (Slot) | The account owner has finished ownership verification (the account is registered on-chain to the account owner's wallet). The account is not listed for sale, not deleted and not already leased. Agent accounts cannot be leased.계정 소유자가 소유권 인증을 마친 계정(체인에 계정 소유자 지갑이 소유자로 등록됨)이어야 합니다. 판매 등록·삭제·대여 중인 계정은 안 됩니다. 에이전트용 계정은 대여 대상이 아닙니다. |
| one at a time | One active lease per account. Re-lending a borrowed account is not allowed.계정당 활성 대여는 1건입니다. 빌린 계정을 다시 빌려줄 수 없습니다. |
| end | Automatic return at expiry, or instant recall by the account owner at any time.만료 시 자동 반환되거나, 계정 소유자가 언제든 즉시 회수할 수 있습니다. |
What an account borrower cannot do. While an account is borrowed, the A server rejects ownership verification, owner transfer, nickname and image changes, deletion, sale listing and in-app purchases paid from the account wallet (XOR payment) with SLOT_LEASED. The platform UI also hides key recovery and agent mode for borrowed accounts. An account that is lent out cannot be listed, transferred or deleted either. The account owner must recall it first.
계정 대여자가 할 수 없는 것. 대여 중인 계정에서는 A 서버가 소유권 인증·소유자 이전·닉네임/이미지 변경·삭제·판매 등록·계정 지갑으로 결제하는 인앱 구매(XOR 결제)를 SLOT_LEASED 로 거부합니다. 플랫폼 화면도 빌린 계정에서는 키 복구·에이전트 모드를 숨깁니다. 빌려준 계정도 판매 등록·이전·삭제를 할 수 없으므로 계정 소유자가 먼저 회수해야 합니다.
dex v2 cannot be upgraded and has no time field, so leases live in a separate contract. SlotLease only reads the account (Slot) owner from dex v2. It records who may use the account and until when. dex v2 itself is unchanged. dex v2 는 업그레이드할 수 없고 시간 필드도 없어서, 대여는 별도 컨트랙트에 둡니다. SlotLease 는 dex v2 에서 계정(Slot) 소유자만 읽고, 누가 언제까지 쓰는지만 기록합니다. dex v2 자체는 바뀌지 않았습니다.
| Item항목 | Value값 |
|---|---|
| SlotLease | 0x2A99c5d7A214054dC60FC4ceaee3061F250ad04a (XOTN chain, deployed at block 4283121)(XOTN 체인, 4283121 블록에서 배포) |
| dex v2 | 0xa27a0152b4A9eC5136D8a74623B5e749c9aaCDE0 (unchanged, source of account ownership)(변경 없음, 계정 소유권의 정본) |
| clock | block.timestamp is the only clock. Server clocks are never used to decide expiry.만료 판정의 기준은 block.timestamp 하나뿐입니다. 서버 시계로는 만료를 판정하지 않습니다. |
| Field필드 | Type타입 | Meaning의미 |
|---|---|---|
| lessor | address | Account owner (lessor) at lease time. The account goes back to this address.대여 시점의 계정 소유자(lessor). 계정은 이 주소로 돌아갑니다. |
| lessee | address | Account borrower (lessee) wallet.계정 대여자(lessee) 지갑. |
| startAt | uint64 | Block time of create_lease.create_lease 블록 시각. |
| expiresAt | uint64 | Expiry in Unix seconds.만료 시각(유닉스 초). |
| status | uint8 | 0 none, 1 active, 2 ended by expiry, 3 recalled, 4 voided. Only the latest lease is kept, and the next create_lease overwrites an ended one.0 없음, 1 활성, 2 만료 반환, 3 회수, 4 무효. 최근 1건만 남고, 끝난 기록은 다음 create_lease 가 덮어씁니다. |
| Function함수 | Who can call호출 가능자 | Checks and effect검증과 결과 |
|---|---|---|
| create_lease(slot, lessor, lessee, expiresAt) | account owner (lessor) or platform계정 소유자(lessor) 또는 플랫폼 | dex v2 owner must equal lessor. lessee is not zero and not the account owner. No active lease. expiresAt is in the future. Sets status 1 and emits LeaseCreated.dex v2 소유자가 lessor 와 같아야 합니다. lessee 는 0 주소도 계정 소유자도 아니어야 하고, 활성 대여가 없어야 하며, expiresAt 은 미래여야 합니다. status 를 1 로 두고 LeaseCreated 를 남깁니다. |
| recall(slot) | account owner (lessor) or platform계정 소유자(lessor) 또는 플랫폼 | Active lease only, before or after expiry. Sets status 3 and emits LeaseEnded with reason 3.활성 대여만, 만료 전후 언제든. status 3, LeaseEnded(reason 3). |
| end_expired(slot) | anyone누구나 | Active and block.timestamp >= expiresAt. Sets status 2 and emits LeaseEnded with reason 2. Because anyone can call it, the platform can return an account without anyone's PIN.활성이고 block.timestamp >= expiresAt 일 때. status 2, LeaseEnded(reason 2). 누구나 호출할 수 있어서 플랫폼이 누구의 PIN 없이도 반환할 수 있습니다. |
| void_if_owner_changed(slot) | anyone누구나 | Active and the dex v2 owner is no longer the account owner. Sets status 4 and emits LeaseEnded with reason 4. This is a safety net. The A server already blocks owner changes on leased accounts, and no server calls it automatically today.활성이고 dex v2 소유자가 더 이상 계정 소유자가 아닐 때. status 4, LeaseEnded(reason 4). 안전장치입니다. A 서버가 대여 중 소유자 변경을 이미 막고 있어서 지금은 어느 서버도 자동으로 호출하지 않습니다. |
| get_lease(slot) | view조회 | (lessor, lessee, startAt, expiresAt, status) |
| is_active(slot) / is_expired(slot) | view조회 | is_active is status 1 and not yet expired. is_expired is status 1 and past expiresAt, which means it is waiting for end_expired.is_active 는 status 1 이고 아직 만료 전, is_expired 는 status 1 인데 expiresAt 을 지나 end_expired 를 기다리는 상태입니다. |
event LeaseCreated(address indexed slot, address indexed lessor, address indexed lessee, uint64 startAt, uint64 expiresAt)
event LeaseEnded(address indexed slot, address indexed lessor, address indexed lessee, uint8 reason) // reason 2 expired · 3 recalled · 4 voided
The A server (OAuth) decides who can sign in to an account (Slot). The B server (blockchain) reads the chain, sends transactions with the platform key and indexes events. The A server never talks to the chain directly. It asks the B server. A 서버(OAuth)는 누가 계정(Slot)으로 로그인할 수 있는지 정합니다. B 서버(블록체인)는 체인을 읽고, 플랫폼 키로 트랜잭션을 보내고, 이벤트를 색인합니다. A 서버는 체인과 직접 통신하지 않고 B 서버에 묻습니다.
slot_lease keeps each offer and lease. Status is one of offered, active, ended, recalled, voided, declined, cancelled, expired_offer. A unique lock allows only one active row per account. expires_at is copied from the chain value.
slot_lease 테이블이 제안과 대여를 1건씩 보관합니다. 상태는 offered·active·ended·recalled·voided·declined·cancelled·expired_offer 중 하나입니다. 유니크 잠금으로 계정당 active 행은 1개만 허용합니다. expires_at 은 체인 값을 복사한 것입니다.
user_uuid is switched to the account borrower (lessee) and lease_state becomes borrowed. Every existing sign-in path then works for the account borrower without changes. transfer_cnt does not increase because ownership does not move.
대여가 활성인 동안 계정 행의 user_uuid 는 계정 대여자(lessee)로 바뀌고 lease_state 는 borrowed 가 됩니다. 그래서 기존 로그인 경로가 수정 없이 계정 대여자에게 동작합니다. 소유권 이동이 아니므로 transfer_cnt 는 늘지 않습니다.
| Where위치 | When주기 | What it does하는 일 |
|---|---|---|
| A login hook | Each use of a borrowed account빌린 계정 사용 시마다 | PKCE /v1/oauth2/code, code exchange and refresh at /v1/oauth2/token, and legacy oauth-meta/authorize and oauth-meta/get_token (code and refresh). It asks the B server for the lease and the latest block time. If expired, it ends the lease on-chain, returns the account and rejects the request with SLOT_LEASE_EXPIRED. Accounts that are not borrowed skip this check.PKCE /v1/oauth2/code, /v1/oauth2/token 의 코드 교환·리프레시, 레거시 oauth-meta/authorize·oauth-meta/get_token(code·refresh). B 서버에 대여 상태와 최신 블록 시각을 묻고, 만료면 체인에서 대여를 끝내고 계정을 돌려준 뒤 SLOT_LEASE_EXPIRED 로 거부합니다. 빌린 계정이 아니면 이 검사를 건너뜁니다. |
| A sweep | Every 60 s60초 | Compares every active row with the chain and returns expired or ended leases. Finishes activations whose chain write succeeded but DB update failed. Closes offers older than 72 hours as expired_offer. Idempotent.활성 행을 모두 체인과 대조해 만료·종료된 대여를 반환합니다. 체인 기록은 됐지만 DB 전이가 실패한 수락을 마무리합니다. 72시간이 지난 제안은 expired_offer 로 닫습니다. 멱등입니다. |
| B indexer | Every 15 s15초 | Reads LeaseCreated and LeaseEnded logs from a block cursor into slot_lease_event and keeps the current state in slot_lease_state.블록 커서부터 LeaseCreated·LeaseEnded 로그를 읽어 slot_lease_event 에 쌓고, 현재 상태를 slot_lease_state 에 유지합니다. |
| B sweep | Every 5 min5분 | Lists expired active leases from the index, rechecks is_expired on-chain, calls end_expired with the platform key and then notifies the A server at POST /v1/lease/internal/ended.색인에서 만료된 활성 대여를 찾고, 체인에서 is_expired 를 다시 확인한 뒤 플랫폼 키로 end_expired 를 보내고 A 서버 POST /v1/lease/internal/ended 로 알립니다. |
The rule is chain first, then database. The A server changes who can sign in only after the chain transaction succeeds. So the database can lag behind the chain, but it never shows a lease the chain does not have. 원칙은 체인 먼저, DB 나중입니다. A 서버는 체인 트랜잭션이 성공한 뒤에만 로그인 권한을 바꿉니다. 그래서 DB 가 체인보다 늦을 수는 있어도, 체인에 없는 대여가 DB 에만 있는 일은 없습니다.
Legend: lessor = account owner, lessee = account borrower. 범례. lessor = 계정 소유자, lessee = 계정 대여자.
OFFER lessor ─(PIN)→ A /v1/lease/offer ─→ B VerifyWalletOwner [off-chain only, row = offered]
ACCEPT lessee ─→ A /v1/lease/accept
A ─→ B GetLatestBlockTs expiresAt = latest block time + duration
A ─→ B CreateSlotLease ─→ SlotLease.create_lease (platform key, dex owner == lessor)
receipt ok ─→ A DB: user_uuid = lessee, lease_state = borrowed, lessor tokens revoked, row = active
USE lessee app ─→ A /v1/oauth2/code · /token · refresh · legacy authorize · get_token
A ─→ B GetSlotLeaseStatus get_lease + latest block time
├─ not expired ─→ normal sign-in
└─ expired ─→ B end_expired ─→ A returns slot ─→ SLOT_LEASE_EXPIRED
RETURN (a) login hook above
(b) B sweep 5 min: index ─→ is_expired? ─→ end_expired ─→ A POST /v1/lease/internal/ended
(c) A sweep 60 s: get_lease ─→ expired: end_expired + return · already ended: return
RECALL lessor ─(PIN)→ A /v1/lease/recall ─→ B RecallSlotLease ─→ SlotLease.recall
receipt ok ─→ A DB: user_uuid = lessor, lessee tokens revoked, row = recalled
INDEX B indexer 15 s: LeaseCreated / LeaseEnded ─→ slot_lease_event, slot_lease_state
| Step단계 | On-chain온체인 | Off-chain오프체인 |
|---|---|---|
| 1. Offer | Nothing.없음. | The A server checks the account (Slot) and the account borrower (lessee), then verifies the account owner's (lessor's) PIN through the B server. The PIN and key share are not stored. The row is offered for 72 hours.A 서버가 계정(Slot)과 계정 대여자(lessee)를 검사하고, B 서버를 통해 계정 소유자(lessor) PIN 을 검증합니다. PIN 과 키 조각은 저장하지 않습니다. 행은 72시간 동안 offered 입니다. |
| 2. Accept | The platform key sends create_lease. The contract checks again that the account owner still owns the account on dex v2.플랫폼 키가 create_lease 를 보냅니다. 컨트랙트가 계정 소유자가 아직 dex v2 소유자인지 다시 확인합니다. |
No PIN at this point, because it was checked at offer time. expiresAt is the latest block time plus the duration. After the receipt, the A server moves the account to the account borrower in one DB transaction.PIN 은 제안 때 검증했으므로 이 단계에는 없습니다. expiresAt 은 최신 블록 시각에 기간을 더한 값입니다. 영수증을 받은 뒤 A 서버가 한 DB 트랜잭션으로 계정을 계정 대여자에게 넘깁니다. |
| 3. Use | Read only: get_lease and the latest block.조회만. get_lease 와 최신 블록. |
The login hook compares the latest block time with expiresAt. If the B server cannot be reached, the hook lets the request through on the DB state and the sweeps catch up later.로그인 훅이 최신 블록 시각과 expiresAt 을 비교합니다. B 서버에 닿지 않으면 DB 상태대로 통과시키고, 나중에 스윕이 따라잡습니다. |
| 4. Return | end_expired, reason 2.end_expired, reason 2. |
Whichever comes first: the login hook, the A sweep (60 s) or the B sweep (5 min). The account goes back to the account owner and the account borrower's tokens are revoked.로그인 훅, A 스윕(60초), B 스윕(5분) 중 먼저 오는 쪽이 처리합니다. 계정은 계정 소유자에게 돌아가고 계정 대여자 토큰은 폐기됩니다. |
| 5. Recall | recall, reason 3.recall, reason 3. |
The B server verifies the account owner's PIN and that the account owner recorded on-chain is the caller's wallet, then sends with the platform key. The account borrower's tokens are revoked immediately.B 서버가 계정 소유자 PIN 과 온체인에 기록된 계정 소유자가 호출자 지갑인지 확인한 뒤 플랫폼 키로 보냅니다. 계정 대여자 토큰은 즉시 폐기됩니다. |
| Case상황 | Recovery복구 |
|---|---|
| Accept: chain succeeded, DB update failed수락. 체인 성공, DB 전이 실패 | The row stays offered with the transaction hash. The A sweep activates it if the chain lease is active, or marks it voided if not.행은 tx 해시를 가진 offered 로 남습니다. A 스윕이 체인 대여가 활성이면 활성화하고, 아니면 voided 로 닫습니다. |
| Accept: account changed between the chain write and the DB update수락. 체인 기록과 DB 전이 사이에 계정 상태가 바뀜 | The offer is closed as voided and sign-in rights do not move. The chain lease stays until expiry, then the B sweep ends it.제안은 voided 로 닫히고 로그인 권한은 넘어가지 않습니다. 체인 대여는 만료까지 남았다가 B 스윕이 끝냅니다. |
| Recall: chain succeeded, DB update failed회수. 체인 성공, DB 역전이 실패 | The A sweep sees status 3 on-chain and returns the account.A 스윕이 체인 status 3 을 보고 계정을 돌려줍니다. |
| B sweep ended the lease but the A callback failedB 스윕이 대여를 끝냈지만 A 콜백 실패 | The A sweep sees status 2 on-chain and returns the account.A 스윕이 체인 status 2 를 보고 계정을 돌려줍니다. |
Expired, but the end_expired transaction failed만료됐지만 end_expired tx 실패 |
Block time already says expired, so the A server returns the account anyway. The B sweep closes the chain lease later.블록 시각상 이미 만료이므로 A 서버는 계정을 그대로 돌려줍니다. 체인 대여는 나중에 B 스윕이 닫습니다. |
| dex v2 owner changed during a lease대여 중 dex v2 소유자 변경 | Anyone can call void_if_owner_changed. The A sweep then sees status 4 and closes the row as voided.누구나 void_if_owner_changed 를 호출할 수 있습니다. 그러면 A 스윕이 체인 status 4 를 보고 행을 voided 로 닫습니다. |
All lease fields are additive. Apps that ignore them keep working. During a lease, the account (Slot) ID stays the same and user_uuid is the account borrower (lessee).
대여 관련 필드는 모두 추가된 필드입니다. 무시해도 앱은 그대로 동작합니다. 대여 중에도 계정(Slot) ID 는 같고 user_uuid 는 계정 대여자(lessee)입니다.
| Response응답 | Field필드 | Meaning의미 |
|---|---|---|
Token response (/v1/oauth2/token, code and refresh)토큰 응답(/v1/oauth2/token, code·refresh) |
slot.lease | { state, expires_at }. state is none or borrowed. expires_at is ISO 8601 UTC, or null when none.{ state, expires_at }. state 는 none 또는 borrowed. expires_at 은 ISO 8601 UTC 이고 none 이면 null. |
user_info (oauth-info/user_info)user_info(oauth-info/user_info) |
lease | Same shape, at the top level of the data item next to user_uuid, because this response has no slot object.같은 형식입니다. 이 응답에는 slot 객체가 없어서 data 항목 최상위, user_uuid 옆에 있습니다. |
| Account list and account detail (platform)계정 목록·상세(플랫폼) | lease_state lease_expires_at lease_id |
lease_state is none or borrowed. The other two are set only while a lease is active, otherwise null. A lent account appears in the account borrower's (lessee's) list, not the account owner's (lessor's). The account owner sees it in GET /v1/lease/mine under lent.lease_state 는 none 또는 borrowed 입니다. 나머지 두 값은 대여가 활성일 때만 있고 아니면 null 입니다. 빌려준 계정은 계정 소유자(lessor)가 아니라 계정 대여자(lessee)의 목록에 나옵니다. 계정 소유자는 GET /v1/lease/mine 의 lent 에서 봅니다. |
"slot": {
"id": 42,
"token_nickname": "...",
"content_address": "0x...",
"tr_cnt": 0,
"lease": { "state": "borrowed", "expires_at": "2026-11-08T03:13:05.000Z" }
}
| Call호출 | Response after the lease ends대여가 끝난 뒤의 응답 |
|---|---|
| /v1/oauth2/token | HTTP 400 {"error":"invalid_grant","error_description":"SLOT_LEASE_EXPIRED"} when this call itself detects the expiry. If a sweep returned the account first, the token is already revoked and you get a plain invalid_grant for the refresh token.이 호출이 만료를 처음 감지하면 HTTP 400 {"error":"invalid_grant","error_description":"SLOT_LEASE_EXPIRED"}. 스윕이 먼저 반환했다면 토큰이 이미 폐기되어 refresh token 에 대한 일반 invalid_grant 가 옵니다. |
| /v1/oauth2/code | HTTP 400 {"success":false,"code":"SLOT_LEASE_EXPIRED","message":"..."}HTTP 400 {"success":false,"code":"SLOT_LEASE_EXPIRED","message":"..."} |
| oauth-meta/authorize, get_token | HTTP 400 {"success":false,"code":400,"data":"SLOT_LEASE_EXPIRED"}HTTP 400 {"success":false,"code":400,"data":"SLOT_LEASE_EXPIRED"} |
| oauth-info/user_info | The revoked access token is no longer found: {"success":false,"code":600}.폐기된 access token 은 더 이상 조회되지 않아 {"success":false,"code":600} 이 옵니다. |
Revocation is immediate on the AltsCodex side, but your own app session is not. If your app or game server keeps its own session after sign-in, an account borrower stays inside until your app calls AltsCodex again. Check the token on resume and at regular intervals if you need a hard cut-off. AltsCodex 쪽 폐기는 즉시이지만 앱 자체 세션은 그렇지 않습니다. 로그인 후 앱이나 게임 서버가 자체 세션을 유지하면, 계정 대여자는 앱이 AltsCodex 를 다시 호출할 때까지 접속해 있습니다. 확실히 끊어야 한다면 앱 복귀 시와 주기적으로 토큰을 확인하세요.
user_uuid. The account borrower plays the account owner's account, and user_uuid switches back when the lease ends.
게임 데이터는 user_uuid 가 아니라 계정 ID 로 묶으세요. 계정 대여자는 계정 소유자의 계정으로 플레이하고, 대여가 끝나면 user_uuid 가 원래대로 돌아갑니다.
lease.state is borrowed, show the remaining time from expires_at and warn before it runs out.
lease.state 가 borrowed 면 expires_at 으로 남은 시간을 보여 주고, 만료 전에 미리 알려 주세요.
invalid_grant, SLOT_LEASE_EXPIRED and user_info code 600 as "signed out". Clear local tokens and send the user back to sign-in. When the description is SLOT_LEASE_EXPIRED, say that the lease period has ended.
invalid_grant, SLOT_LEASE_EXPIRED, user_info 코드 600 은 "로그아웃됨"으로 처리하세요. 로컬 토큰을 지우고 로그인으로 돌려보냅니다. 설명이 SLOT_LEASE_EXPIRED 면 대여 기간이 끝났다고 안내하세요.
SLOT_LEASED: in-app purchase paid from the account wallet (XOR payment), nickname and image change, deletion, sale listing, owner transfer and ownership verification. Hide or disable them when lease.state is borrowed.
빌린 계정에서는 다음 호출이 SLOT_LEASED 를 돌려줍니다. 계정 지갑으로 결제하는 인앱 구매(XOR 결제), 닉네임·이미지 변경, 삭제, 판매 등록, 소유자 이전, 소유권 인증. lease.state 가 borrowed 면 이 기능을 숨기거나 비활성화하세요.
These endpoints are called by the AltsCodex platform (webxcom) with the platform session JWT (Authorization: Bearer). Apps do not call them with an app access token. They are listed so you can read account (Slot) lease states and error codes.
이 엔드포인트는 AltsCodex 플랫폼(webxcom)이 플랫폼 세션 JWT(Authorization: Bearer)로 호출합니다. 앱이 앱 access token 으로 부르는 API 가 아닙니다. 계정(Slot) 대여 상태와 오류 코드를 이해하는 데 참고하세요.
Every response is HTTP 200 with {"success": boolean, "code": string, "data": ...}, including failures. code is OK on success. A missing or invalid JWT returns {"success":false,"code":"UNAUTHORIZED","data":null}. Times are ISO 8601 UTC. duration_text looks like "3 day".
실패를 포함해 모든 응답은 HTTP 200 이고 형식은 {"success": boolean, "code": string, "data": ...} 입니다. 성공이면 code 는 OK 입니다. JWT 가 없거나 무효하면 {"success":false,"code":"UNAUTHORIZED","data":null} 입니다. 시각은 ISO 8601 UTC, duration_text 는 "3 day" 형태입니다.
| Endpoint엔드포인트 | Body and data본문과 data | Failure codes실패 코드 |
|---|---|---|
| POST /v1/lease/offer | Caller is the account owner (lessor). {meta_idx, lessee_uuid, duration:{unit, value}, pin_hash, key_share_user} → {lease_id, duration_text, offer_expires_at}호출자 = 계정 소유자(lessor). {meta_idx, lessee_uuid, duration:{unit, value}, pin_hash, key_share_user} → {lease_id, duration_text, offer_expires_at} |
LEASE_DISABLED SLOT_NOT_FOUND NOT_SLOT_OWNER SLOT_AGENT SLOT_NOT_VERIFIED SLOT_LISTED SLOT_LEASED OFFER_EXISTS LESSEE_NOT_FOUND LESSEE_IS_SELF INVALID_DURATION PIN_INVALID CHAIN_ERROR |
| POST /v1/lease/accept | Caller is the account borrower (lessee). {lease_id} → {lease_id, tx_hash, starts_at, expires_at}호출자 = 계정 대여자(lessee). {lease_id} → {lease_id, tx_hash, starts_at, expires_at} |
LEASE_DISABLED OFFER_NOT_FOUND OFFER_EXPIRED NOT_LESSEE SLOT_STATE_CHANGED LESSEE_SLOT_LOGGED_IN CHAIN_ERROR |
| POST /v1/lease/decline | Caller is the account borrower. {lease_id} → {lease_id}호출자 = 계정 대여자. {lease_id} → {lease_id} |
OFFER_NOT_FOUND NOT_LESSEE |
| POST /v1/lease/cancel_offer | Caller is the account owner. {lease_id} → {lease_id}호출자 = 계정 소유자. {lease_id} → {lease_id} |
OFFER_NOT_FOUND NOT_LESSOR |
| POST /v1/lease/recall | Caller is the account owner. {lease_id, pin_hash, key_share_user} → {lease_id, tx_hash}호출자 = 계정 소유자. {lease_id, pin_hash, key_share_user} → {lease_id, tx_hash} |
LEASE_NOT_FOUND NOT_LESSOR LEASE_NOT_ACTIVE PIN_INVALID CHAIN_ERROR |
| GET /v1/lease/mine | {lent, borrowed, offers_received, offers_sent, history}. lent and borrowed hold active leases only. history holds ended leases and closed offers, newest first, up to 50.{lent, borrowed, offers_received, offers_sent, history}. lent·borrowed 는 활성 대여만, history 는 끝난 대여와 닫힌 제안을 최신순 최대 50건 담습니다. |
- |
| GET /v1/lease/resolve_lessee | Query wallet_address (0x + 40 hex, case-insensitive) → {user_uuid, wallet_address}. Use user_uuid as lessee_uuid in the offer.쿼리 wallet_address(0x + 16진수 40자리, 대소문자 무시) → {user_uuid, wallet_address}. 받은 user_uuid 를 제안의 lessee_uuid 로 씁니다. |
INVALID_ARGUMENT LESSEE_NOT_FOUND LESSEE_IS_SELF |
Each item in mine has lease_id, meta_idx, client_cuid, token_nickname, lessor_uuid, lessee_uuid, status, duration_text, starts_at, expires_at, offer_expires_at, create_tx, end_tx, end_reason. end_reason uses the on-chain reason (2, 3, 4).
mine 의 각 항목은 lease_id, meta_idx, client_cuid, token_nickname, lessor_uuid, lessee_uuid, status, duration_text, starts_at, expires_at, offer_expires_at, create_tx, end_tx, end_reason 을 가집니다. end_reason 은 온체인 reason(2·3·4)과 같습니다.
| Code코드 | Meaning의미 |
|---|---|
| SLOT_NOT_VERIFIED | The account owner has not finished ownership verification for this account.계정 소유자가 이 계정의 소유권 인증을 마치지 않았습니다. |
| SLOT_AGENT | Agent accounts cannot be leased.에이전트용 계정은 대여할 수 없습니다. |
| SLOT_LISTED | The account is listed for sale.판매 등록된 계정입니다. |
| SLOT_LEASED | The account is already leased, or the action is not allowed during a lease.이미 대여 중이거나, 대여 중에는 할 수 없는 동작입니다. |
| LESSEE_NOT_FOUND | No active user, or the user has no wallet address. The chain needs the account borrower's address.활성 사용자가 없거나 지갑 주소가 없습니다. 체인에 계정 대여자 주소가 필요합니다. |
| INVALID_DURATION | Unknown unit, value not a positive integer, or longer than 5 years.단위가 틀렸거나, 값이 양의 정수가 아니거나, 5년을 넘습니다. |
| LESSEE_SLOT_LOGGED_IN | The account borrower is signed in to their own account of the same app. They must sign out of it before accepting.계정 대여자가 같은 앱의 자기 계정으로 로그인 중입니다. 수락 전에 로그아웃해야 합니다. |
| SLOT_STATE_CHANGED | The account changed after the offer (sold, listed, verified owner changed and so on).제안 이후 계정 상태가 바뀌었습니다(판매·판매 등록·소유자 변경 등). |
| CHAIN_ERROR | The B server or the chain failed. Nothing changed in the database.B 서버나 체인에서 실패했습니다. DB 는 바뀌지 않았습니다. |
| LEASE_DISABLED | New offers and accepts are switched off. Recall and expiry return keep working.새 제안·수락이 꺼져 있습니다. 회수와 만료 반환은 계속 동작합니다. |
expires_at, then refresh the token or sign in again.
테스트 계정(Slot)을 1~2분 빌려주면 만료 흐름 전체를 빠르게 볼 수 있습니다. 계정 대여자(lessee)로 앱에 로그인하고, expires_at 이 지난 뒤 토큰을 리프레시하거나 다시 로그인해 보세요.
SLOT_LEASE_EXPIRED. If you wait longer, a sweep may have returned the account already and you see a plain invalid_grant or user_info code 600. Your app should handle both.
만료 직후 바로 호출하면 대개 로그인 훅이 먼저 잡아 SLOT_LEASE_EXPIRED 를 봅니다. 더 기다리면 스윕이 이미 반환해 일반 invalid_grant 나 user_info 코드 600 이 옵니다. 앱은 둘 다 처리해야 합니다.
create_tx or end_tx, or call get_lease(slot) on the SlotLease contract.
체인 쪽은 create_tx·end_tx 의 트랜잭션 해시로 확인하거나, SlotLease 컨트랙트의 get_lease(slot) 를 호출해 확인하세요.