Skip to content

me.virmesh.avatar.resolveAvatar

avatar id から署名付き avatar manifest を解決します。

AvatarServer が保持する avatar manifest を取得する public action です。 public avatar は query.avatarId だけで解決できます。 private avatar は world relay 経由で wearer が発行した短命 fetchGrant を添えた場合だけ解決できます。 重い model、thumbnail、WASM script は manifest 内の URL から通常 HTTP で取得します。 fetchGrant はこの action にだけ送り、manifest 内の asset URL への request には転送しません。 private avatar の asset URL は、AvatarServer が grant 検証後に返す短命 signed URL または grant-bound URL にします。

draft

Endpoint

Method
GET
Path
/public/me.virmesh.avatar.resolveAvatar
Auth
none
Host
VirMesh.AvatarServer

Request schema

query.avatarIdstringRequired

解決する avatar identifier です。形式は medi:avatar:<scheme>:<publicKey> です。

query.versionIdstringOptional

特定の manifest version を要求します。query.hash とは同時指定しません。

query.hashstringOptional

特定の manifest hash を要求します。query.versionId とは同時指定しません。

query.fetchGrantavatarFetchGrantOptional

private avatar を解決するときにこの action へ送る短命 grant です。public avatar では不要です。asset URL への request には送りません。

References obj+me.virmesh.avatar.fetchGrant : private avatar を取得するために wearer が発行する短命 grant です。

payload.avatarIdstringRequired

取得を許可する avatar identifier です。

payload.versionIdstringOptional

許可する manifest version です。payload.hash とは同時指定しません。

payload.hashstringOptional

許可する manifest または asset hash です。payload.versionId とは同時指定しません。

payload.wearerIdstringRequired

grant を発行した wearer の player identifier です。

payload.viewerIdstringRequired

private avatar を取得できる viewer の player identifier です。

payload.issuedAtintegerRequired

grant を発行した epoch second です。AvatarServer はこの時刻から短い許容時間内の grant だけを受け付けます。

signaturestringRequired

canonical JSON of payload に対する wearer の署名です。

Request example

{
  "query": {
    "avatarId": "medi:avatar:ed25519:avatar-public-key",
    "versionId": "2026-04-11T00:00:00Z",
    "fetchGrant": {
      "payload": {
        "avatarId": "medi:avatar:ed25519:avatar-public-key",
        "versionId": "2026-04-11T00:00:00Z",
        "wearerId": "medi:player:ed25519:wearer-public-key",
        "viewerId": "medi:player:ed25519:viewer-public-key",
        "issuedAt": 1770000000
      },
      "signature": "base64-signature-by-wearer"
    }
  }
}

Responses

200
status+me.virmesh.success.avatarResolved

avatar manifest が正常に解決されたことを示します。

Response body

payload.manifestavatarManifestRequired

解決された avatar manifest です。

References obj+me.virmesh.avatar.manifest : AvatarServer が返す署名対象の avatar manifest です。

avatarIdstringRequired

avatar identifier です。形式は medi:avatar:<scheme>:<publicKey> です。

versionIdstringRequired

manifest の immutable version identifier です。

endpointstringRequired

この manifest を解決する AvatarServer の absolute URL です。

namestringRequired

表示用の avatar 名です。

visibilitystringRequired

public または private です。

publisherDelegationavatarPublisherDelegationRequired

publisher が avatar 鍵をこの avatar 用に委任したことを示す署名付き object です。

References obj+me.virmesh.avatar.publisherDelegation : publisher が avatar 鍵と publisher identity の対応を署名した object です。

payload.avatarIdstringRequired

委任先の avatar identifier です。

payload.publisher.idstringRequired

publisher の player identifier です。

payload.publisher.handlestringOptional

publisher の表示用 handle snapshot です。

payload.issuedAtintegerRequired

delegation を発行した epoch second です。

payload.expiresAtintegerOptional

delegation の任意の期限です。epoch second で表します。

signaturestringRequired

canonical JSON of payload に対する publisher の署名です。

assetsobject[]Required

model などの重い asset entry 一覧です。各 entry は kind, contentType, profile, url, hash, size を持ちます。

assets[].kindstringRequired

model などの asset 種別です。

assets[].contentTypestringRequired

HTTP content type です。

assets[].profilestringRequired

vrm, glb, gltf などの実装 profile です。

assets[].urlstringRequired

asset を取得する absolute URL です。private avatar では、fetchGrant を再送せずに使える短命 signed URL または grant-bound URL にします。

assets[].hashstringRequired

asset body の content hash です。v1 では sha256:<base64url> を使います。

assets[].sizeintegerRequired

asset body の byte size です。

thumbnailobjectOptional

任意の thumbnail asset entry です。contentType, profile, url, hash, size を持ちます。

purchaseReceiptavatarPurchaseReceiptOptional

wearer が提示する任意の購入 receipt claim です。

References obj+me.virmesh.avatar.purchaseReceipt : seller が buyer に対して発行した avatar purchase receipt claim です。

payload.avatarIdstringRequired

購入対象の avatar identifier です。

payload.shopUrlstringRequired

購入元ショップページの absolute URL です。

payload.seller.idstringRequired

seller の player identifier です。

payload.seller.handlestringOptional

seller の表示用 handle snapshot です。

payload.buyer.idstringRequired

buyer の player identifier です。

payload.buyer.handlestringOptional

buyer の表示用 handle snapshot です。

payload.issuedAtintegerRequired

receipt を発行した epoch second です。

signaturestringRequired

canonical JSON of payload に対する seller の署名です。

scriptavatarScriptSandboxOptional

任意の WASM script と sandbox policy です。

References obj+me.virmesh.avatar.scriptSandbox : avatar WASM script と v1 sandbox policy を表す object です。

urlstringRequired

WASM binary を取得する absolute URL です。

hashstringRequired

WASM binary body の content hash です。v1 では sha256:<base64url> を使います。

permissionsstring[]Required

script が要求する permission token 一覧です。v1 では avatar.self など低権限の token に限定します。

sandbox.runtimestringRequired

v1 では wasm です。

sandbox.networkbooleanRequired

network access を許可するかです。v1 では false です。

sandbox.filesystembooleanRequired

filesystem access を許可するかです。v1 では false です。

sandbox.worldMutationbooleanRequired

world state mutation を許可するかです。v1 では false です。

sandbox.maxMemoryBytesintegerRequired

script に許可する最大 memory byte 数です。

sandbox.maxExecutionMillisintegerRequired

1 tick または 1 call あたりの最大実行時間です。

signaturestringRequired

canonical JSON of payload.manifest に対する avatar 鍵の署名です。

Response example

{
  "payload": {
    "manifest": {
      "avatarId": "medi:avatar:ed25519:avatar-public-key",
      "versionId": "2026-04-11T00:00:00Z",
      "endpoint": "https://avatars.example.com/",
      "name": "Alice Avatar",
      "visibility": "public",
      "publisherDelegation": {
        "payload": {
          "avatarId": "medi:avatar:ed25519:avatar-public-key",
          "publisher": {
            "id": "medi:player:ed25519:publisher-public-key",
            "handle": "alice@virmesh.me"
          },
          "issuedAt": 1770000000
        },
        "signature": "base64-signature-by-publisher"
      },
      "assets": [
        {
          "kind": "model",
          "contentType": "model/gltf-binary",
          "profile": "glb",
          "url": "https://cdn.example.com/avatars/avatar.glb",
          "hash": "sha256:base64url-hash",
          "size": 2480000
        }
      ],
      "thumbnail": {
        "contentType": "image/png",
        "profile": "png",
        "url": "https://cdn.example.com/avatars/avatar.png",
        "hash": "sha256:base64url-thumbnail-hash",
        "size": 42000
      },
      "script": {
        "url": "https://cdn.example.com/avatars/avatar-script.wasm",
        "hash": "sha256:base64url-script-hash",
        "permissions": [
          "avatar.self"
        ],
        "sandbox": {
          "runtime": "wasm",
          "network": false,
          "filesystem": false,
          "worldMutation": false,
          "maxMemoryBytes": 16777216,
          "maxExecutionMillis": 5
        }
      }
    }
  },
  "signature": "base64-signature-by-avatar-key"
}

この status は me.virmesh.avatar.resolveAvatar が署名付き avatar manifest を返した場合に使います。 private avatar の場合は、有効な fetchGrant が検証済みです。

400
status+me.virmesh.http.invalid_query

query parameter の組み合わせまたは形式が不正であることを示します。

この status は route が期待する query parameter の条件を満たしていない場合に返ります。 resolveHandle では idhandle の同時指定、未指定、未知の key を拒否します。

Status payload

payload.messagestringRequired

実装依存の詳細メッセージです。

handle query is ambiguous

{
  "status": "status+me.virmesh.http.invalid_query",
  "payload": {
    "message": "Specify exactly one of query.id or query.handle."
  }
}
403
status+me.virmesh.avatar.player_not_allowed

対象 viewer が private avatar の取得を許可されていないことを示します。

この status は private avatar の解決で、有効な fetchGrant がない、 または grant の viewerIdwearerId、avatar 条件が一致しない場合に返ります。

Status payload

payload.messagestringRequired

実装依存の詳細メッセージです。

viewer is not allowed

{
  "status": "status+me.virmesh.avatar.player_not_allowed",
  "payload": {
    "message": "This private avatar requires a valid wearer fetchGrant."
  }
}
403
status+me.virmesh.avatar.grant_expired

private avatar の fetchGrant が期限切れであることを示します。

この status は query.fetchGrant.payload.issuedAt から AvatarServer が許容する短い寿命を過ぎている場合に返ります。 v1 の fetchGrant は 60 秒程度の短命 grant として扱います。

Status payload

payload.messagestringRequired

実装依存の詳細メッセージです。

fetch grant expired

{
  "status": "status+me.virmesh.avatar.grant_expired",
  "payload": {
    "message": "The avatar fetchGrant has expired."
  }
}
404
status+me.virmesh.avatar.not_found

指定した avatar id に対応する avatar manifest が存在しないことを示します。

この status は me.virmesh.avatar.resolveAvatar が 指定された query.avatarId に対応する avatar manifest を見つけられなかった場合に返ります。

Status payload

payload.messagestringRequired

実装依存の詳細メッセージです。

avatar not found

{
  "status": "status+me.virmesh.avatar.not_found",
  "payload": {
    "message": "No avatar matched the requested avatarId."
  }
}
409
status+me.virmesh.avatar.hash_mismatch

指定された hash と解決された manifest または asset の hash が一致しないことを示します。

この status は query.hash で特定 hash を要求したが、AvatarServer が返せる manifest または primary asset の hash と一致しない場合に返ります。 クライアント側でも asset 取得後に manifest 内の hash を検証し、一致しない asset はロードしません。

Status payload

payload.messagestringRequired

実装依存の詳細メッセージです。

avatar hash mismatch

{
  "status": "status+me.virmesh.avatar.hash_mismatch",
  "payload": {
    "message": "Requested avatar hash does not match the resolved manifest."
  }
}
422
status+me.virmesh.avatar.invalid_manifest_signature

avatar manifest の署名検証に失敗したことを示します。

この status は AvatarServer が保存している manifest 署名を検証できない場合、 または publisher delegation の署名検証に失敗した場合に返ります。 クライアントも response の signaturepublisherDelegation.signature を検証してから manifest を使います。

Status payload

payload.messagestringRequired

実装依存の詳細メッセージです。

manifest signature failed

{
  "status": "status+me.virmesh.avatar.invalid_manifest_signature",
  "payload": {
    "message": "Avatar manifest signature verification failed."
  }
}