{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://aidid.im/schemas/login/signin-request.schema.json",
  "title": "AIDID Sign-in Request",
  "description": "The request an RP (relying party) generates before a user signs in. Shipped to the wallet as `web+aidid://auth?payload=<uri-encoded JSON>` (or a QR code of the same string). The RP MUST keep its own copy and verify the response against THAT copy — never against the echoed request.",
  "type": "object",
  "additionalProperties": false,
  "required": ["type", "version", "domain", "uri", "nonce", "chainId", "issuedAt", "expirationTime"],
  "properties": {
    "type": {
      "const": "auth"
    },
    "version": {
      "const": "1.0"
    },
    "domain": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[^\\r\\n]+$",
      "description": "Requesting site. May include a port. Must match the first line of the canonical sign-in message."
    },
    "uri": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[^\\r\\n]+$",
      "description": "Where the wallet returns the response (`<uri>#response=<uri-encoded JSON>`). MUST be https."
    },
    "nonce": {
      "type": "string",
      "minLength": 16,
      "pattern": "^[^\\r\\n]+$",
      "description": "Single-use, at least 16 characters. The RP is responsible for registering it exactly once."
    },
    "chainId": {
      "enum": ["msg-chain-1"],
      "description": "MUST equal the MSG Chain network chain id (`MSG_NETWORK.chainId` in frontend/lib/msgNetwork.ts)."
    },
    "issuedAt": {
      "type": "string",
      "format": "date-time",
      "description": "ISO-8601 UTC. Part of the signed message, echoed byte-for-byte."
    },
    "expirationTime": {
      "type": "string",
      "format": "date-time",
      "description": "ISO-8601 UTC. Part of the signed message. Default TTL is 5 minutes."
    },
    "statement": {
      "type": "string",
      "pattern": "^[^\\r\\n]+$",
      "description": "Optional human-readable statement shown in the wallet and included in the signed message."
    },
    "requestId": {
      "type": "string",
      "pattern": "^[^\\r\\n]+$",
      "description": "Optional caller correlation id, echoed in the signed message."
    },
    "resources": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string",
        "minLength": 1,
        "pattern": "^[^\\r\\n]+$"
      },
      "description": "Optional ordered list of requested resources. Order is significant; the list is neither sorted nor de-duplicated. The wire type is a FREE string array — no `enum` is imposed (SPEC-LOGIN-v1 §4.1). Conventional reserved words: `did:auth` (the sign-in itself) and `pay:address` (declarative: the RP may read the DID document's `controller`/`owner` account address via its OWN canonical resolve). `pay:address` is NOT a permission grant, does NOT appear in the response, and the wallet must explicitly disclose it (SPEC-LOGIN-v1 §4.1 / §10)."
    }
  },
  "examples": [
    {
      "type": "auth",
      "version": "1.0",
      "domain": "demo-rp.example",
      "uri": "https://demo-rp.example/callback",
      "nonce": "demo-nonce-0123456789abcdef0123456789abcdef",
      "chainId": "msg-chain-1",
      "issuedAt": "2026-09-25T08:00:00.000Z",
      "expirationTime": "2026-09-25T08:05:00.000Z",
      "statement": "Sign in to the offline AIDID demo.",
      "requestId": "offline-demo-1",
      "resources": ["did:auth", "vc:membership"]
    }
  ],
  "x-aidid": {
    "spec": {
      "doc": "AIDID_第三方登录规范_v1.md",
      "section": "§4 / §4.1",
      "version": "v1.3"
    },
    "status": "implemented",
    "source": [
      "frontend/packages/aidid-login-sdk/src/request.js#createSignInRequest",
      "frontend/packages/aidid-login-sdk/src/request.js#validateSignInRequestShape",
      "frontend/lib/protocol.ts#SignInRequest"
    ],
    "honestLimit": "The wire format is implemented and locked by an offline Dilithium-5 vector, but a production flow also needs a chain-side DID resolve endpoint that is not authorized yet (see /status.json)."
  }
}
