addrbookFor publishers
← The evidence ledger

Evidence row 579508

Observed , by probe.mcp/1.

Kind
mcp.tools
About
endpoint 63358b21-79a0-4bc8-97f1-b958c169084b
Recorded
Previous row
None: the first of its kind about this subject
Body SHA-256
84e01f1444eb47478d512e6b3655e6e3370ebc7aba2d574976f725cc234113f7
Leaf
0x9e8e0a352baefe9d9f8f475d5a2d58f3c2ffd2da8b83d3c4861b96fda426f740

What was observed

{
  "count": 3,
  "tools": [
    {
      "description": "Retrieve a PAST CodeRifts decision by exactly one identifier\n(case_id | decision_id | fingerprint): full report, breaking changes, scores,\nand linked receipt metadata if stored.\n\nUse this when:\n- You have a decision_id (or fingerprint) from a previous preflight, PR\n  comment, or CI log and need to inspect or explain that past decision.\n- You are auditing why a prior ALLOW/WARN/BLOCK was issued.\n- You are NOT requesting a new analysis of current before/after specs.\n\nDo not use when:\n- You need a decision for the CURRENT uncommitted or PR head change set —\n  call coderifts.preflight_change_set with the current artifacts.\n- You hold a receipt token and only need cryptographic/lifecycle verification —\n  use coderifts.verify_receipt.\n- You have no identifier — run preflight first to create one.\n\nInputs: exactly one of case_id, decision_id, or fingerprint. {} → INVALID_INPUT;\ntwo identifiers → LOOKUP_IDENTIFIER_CONFLICT; case_id → CASE_NOT_FOUND\n(lookup never opens a case). Returns the stored document or not_found.\n\nScoping — fingerprint lookup returns only YOUR OWN decisions. A fingerprint is\nderived from content, not from an account, so two callers who preflight\nbyte-identical specs derive the same one; the lookup is therefore constrained\nto the decisions your credential can prove it owns.\n\nA decision that exists but is not yours returns the SAME not_found as one that\nwas never issued. This is deliberate: a distinguishable \"exists but forbidden\"\nwould confirm to any caller that a given content hash had been decided on by\nsomeone, which is the fact the scoping exists to withhold. Do not read\nnot_found as proof that no such decision exists anywhere.\n\nDecisions persisted without context.repository cannot currently be attributed\nto an account, and are not retrievable by fingerprint at all — not by their\nowner either. Retrieve those by decision_id, which is unchanged and unscoped.\nThis is a limitation of what older stored rows carry, not a property of the\nlookup: rows written from now on record the account directly, so the gap\nnarrows as older rows age out. If a fingerprint you expect returns not_found,\nuse the decision_id before concluding the decision is missing.\n\nWhen the stored envelope carries control fields, control_envelope.next_agent_step\nis structured remediation guidance the agent MAY follow for non-CONTINUE\nexecution_action values (null on CONTINUE*). Still branch on execution_action;\nnext_agent_step is a suggestion, not permission.",
      "inputSchema": {
        "additionalProperties": false,
        "description": "Closed exclusive identifier union: exactly one of case_id | decision_id | fingerprint. Encoded as minProperties=1 + maxProperties=1 + additionalProperties=false, NOT as a top-level oneOf/anyOf/allOf — Anthropic (and other strict tool APIs) reject those combinators at the root of input_schema and then refuse the entire tools array (measured: test/mcp-input-oneof-honesty.test.js, mcp-streamable.js comment). The server enforces the same mutex with named codes: empty {} → INVALID_INPUT; two or more identifiers → LOOKUP_IDENTIFIER_CONFLICT; case_id alone → CASE_NOT_FOUND (no case store yet; lookup never opens a case).",
        "maxProperties": 1,
        "minProperties": 1,
        "properties": {
          "case_id": {
            "description": "A case identifier. Lookup never opens a case. Until the case store exists this returns CASE_NOT_FOUND.",
            "minLength": 1,
            "type": "string"
          },
          "decision_id": {
            "description": "The decision_id from a prior decision_result envelope. Provide exactly one identifier.",
            "minLength": 1,
            "type": "string"
          },
          "fingerprint": {
            "description": "A verdict fingerprint (sha256:...); returns the latest matching decision you own. Provide exactly one identifier.",
            "minLength": 1,
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "get_decision_details"
    },
    {
      "description": "Use this when: a contract artifact (OpenAPI, GraphQL, protobuf, AsyncAPI, MCP manifests, or agent tool schemas) changes before merge, deploy, publish, or tool registration; AND any agent-executed operation with no supported contract type — send type agent_operation. Do not call for documentation-only changes, static readiness scoring, or receipt verification. Use analyze for risk only; authorize requires context.operation. Skipping this call is not permission. Absence of a key is not permission. Inputs: preflight_mode is required: \"analyze\" (risk only; no receipt, no execution_action) or \"authorize\" (may mint a receipt; requires context.operation — merge is not deploy is not publish). Supply exactly one artifact source: artifacts[] (1–20 items, each {id, type, before, after} as the FULL spec/schema text, not a path or URL; type is openapi|graphql|grpc|asyncapi|mcp_manifest|agent_tools|agent_operation) XOR derivation=\"server\" (server reads GitHub Compare; needs context.repository + context.base + context.head; sending artifacts[] together is 400). Grant fields sit in one object, execution_grant_request {include_execution_grant, grant_version, tenant_id, executor_id, adapter_id, target_uri, expected_state_token, state_nonce, audience, policy_hash}; analyze ignores it; required is preflight_mode only. previous_receipt is a chain token base64url(body).base64url(signature) to LINK a prior decision — it does not re-verify; use coderifts.verify_receipt instead; for details of a past decision use coderifts.get_decision_details instead. idempotency_key replays authorize only (24h), never analyze.",
      "inputSchema": {
        "if": {
          "properties": {
            "preflight_mode": {
              "const": "authorize"
            }
          },
          "required": [
            "preflight_mode"
          ]
        },
        "properties": {
          "artifacts": {
            "description": "1–20 contract documents analyzed together. Each item is {id, type, before, after} where before/after are the FULL document strings (YAML/JSON/proto text), not URLs or file paths. Omit this array entirely when derivation=\"server\".",
            "items": {
              "properties": {
                "after": {
                  "description": "The proposed document as raw text, same kind as before. Must be the bytes you intend to merge/deploy/publish, not a diff.",
                  "type": "string"
                },
                "before": {
                  "description": "The baseline document as raw text (the spec/schema/manifest body). Empty string means \"no prior version\" (create), not \"load from disk\".",
                  "type": "string"
                },
                "id": {
                  "description": "Caller-chosen id, unique within the bundle",
                  "type": "string"
                },
                "type": {
                  "description": "Artifact kind. One of openapi, graphql, grpc, asyncapi, mcp_manifest, agent_tools, agent_operation. Contract types determine how before/after text is parsed. agent_operation: An opaque proposed agent operation for which no supported contract-artifact type applies. CodeRifts does not semantically analyze this content and does not issue an execution grant. Not inferred from the filename.",
                  "enum": [
                    "openapi",
                    "graphql",
                    "grpc",
                    "asyncapi",
                    "mcp_manifest",
                    "agent_tools",
                    "agent_operation"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "id",
                "type",
                "before",
                "after"
              ],
              "type": "object"
            },
            "maxItems": 20,
            "minItems": 1,
            "type": "array"
          },
          "context": {
            "description": "Optional apply-site context folded into the bundle fingerprint. operation distinguishes merge vs deploy vs publish (and other labels); the server accepts any non-empty string; conventional values: merge, deploy, tool_call, publish. The receipt/gate must match this label.",
            "properties": {
              "audience": {
                "description": "Optional audience (IntentContext parity; REST/MCP accept, server-derived audience still wins on the envelope)",
                "type": "string"
              },
              "base": {
                "description": "Base commit/ref SHA the change set was computed against (optional; PR/commit identity)",
                "type": "string"
              },
              "branch": {
                "description": "Branch name (optional; fingerprint context)",
                "type": "string"
              },
              "environment": {
                "description": "Target environment (e.g. production, staging, npm) — optional; folded into fingerprint when set.",
                "type": "string"
              },
              "fingerprint": {
                "description": "Optional change fingerprint (IntentContext parity; not folded into the bundle fingerprint)",
                "type": "string"
              },
              "head": {
                "description": "Head commit/ref SHA of the proposed change (optional; PR/commit identity)",
                "type": "string"
              },
              "operation": {
                "description": "Application operation for this change set (fingerprint + envelope). Server accepts any non-empty string; conventional values: merge, deploy, tool_call, publish. Merge is not deploy is not publish — the receipt/gate must match this label.",
                "type": "string"
              },
              "policy_profile": {
                "description": "Policy profile name (optional; fingerprint context)",
                "type": "string"
              },
              "pull_request": {
                "description": "Pull request id when applicable (optional; fingerprint context)",
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              },
              "repository": {
                "description": "Repository identity (optional; fingerprint context)",
                "type": "string"
              },
              "target_id": {
                "description": "Optional apply-site target (IntentContext parity; not folded into the bundle fingerprint)",
                "type": "string"
              },
              "target_uri": {
                "description": "Optional apply-site URI the cr.exec.v2 grant binds (handler fallback: input.target_uri, then context.target_uri, then repository/head-derived). Distinct from target_id.",
                "type": "string"
              }
            },
            "type": "object"
          },
          "decision_spec_version": {
            "description": "Optional. Omit or '2.0' = current contract. '1.0' retired (INVALID_INPUT); do not pin 1.0.",
            "enum": [
              "2.0"
            ],
            "type": "string"
          },
          "derivation": {
            "description": "\"server\" = the server derives artifacts[] from GitHub Compare via the App installation. Allowed only when context.repository, context.base and context.head are all present and the tenant has a proven binding for that repository. Do not send artifacts[] in the same call (400 — one source of truth). Omit this field for the caller-supplied artifacts[] path.",
            "enum": [
              "server"
            ],
            "type": "string"
          },
          "execution_grant_request": {
            "description": "Authorize + include_execution_grant only: the execution-grant request fields. Analyze ignores them. Flat root-level spellings are also accepted; the same field sent both ways with different values is INVALID_INPUT.",
            "properties": {
              "adapter_id": {
                "description": "Authorize+grant v2 only. Adapter that will apply the change. Conventional values: fs, postgres, git. Must match the adapter the executor actually uses; a git grant does not authorize an fs write.",
                "type": "string"
              },
              "audience": {
                "description": "Requester identity for the decision envelope. Accepted here; the server-derived audience wins when both are present.",
                "type": "string"
              },
              "executor_id": {
                "description": "Authorize+grant v2 only. Executor identity the grant is bound to (example: agent:ci-bot, host:github-actions). Empty/absent is not \"any executor\".",
                "type": "string"
              },
              "expected_state_token": {
                "description": "Authorize+grant v2 only. Compare-and-swap token the executor must observe at apply time (the \"before\" state). Signed as its own field. Omit only if the adapter has no prior state; do not send a placeholder.",
                "type": "string"
              },
              "grant_version": {
                "description": "Grant envelope to mint when include_execution_grant is true. Omitting this yields cr.exec.v1 until 2026-09-18 and cr.exec.v2 on and after it (see x-coderifts-effective-default / x-coderifts-default-changes-at). The response meta.grant_version is the version actually issued. An explicit value always wins — pin \"v1\" to keep current behaviour with no code change on the date.",
                "enum": [
                  "v1",
                  "v2"
                ],
                "type": "string",
                "x-coderifts-default-changes-at": "2026-09-18",
                "x-coderifts-effective-default": "v2"
              },
              "include_execution_grant": {
                "description": "Authorize only. When true on an allow-class authorize, the response includes a signed execution_grant, or HTTP 503 SIGNER_UNAVAILABLE — never an unsigned grant. Default false. Analyze ignores this flag. Ignored unless preflight_mode=\"authorize\".",
                "type": "boolean"
              },
              "policy_hash": {
                "description": "Authorize+grant v2 only. Policy identity bound into the grant, sha256: + 64 hex. When supplied, apply must use that same policy; a different policy is a different grant.",
                "type": "string"
              },
              "state_nonce": {
                "description": "Authorize+grant only. Opaque nonce copied into the signed grant as its own field (not folded into scope_hash). Absent → BEARER grant. Ignored unless include_execution_grant is true.",
                "type": "string"
              },
              "target_uri": {
                "description": "Authorize+grant v2 only. URI the grant binds (example: git://owner/repo.git/refs/heads/main). Fallback if omitted: context.target_uri, then repository/head-derived. Distinct from context.target_id.",
                "type": "string"
              },
              "tenant_id": {
                "description": "Authorize+grant v2 only. Tenant the grant is issued under. ASCII slug. When omitted the server uses \"default\" — pin it if you are not on the default tenant.",
                "type": "string"
              }
            },
            "type": "object"
          },
          "idempotency_key": {
            "description": "Optional client key; in authorize mode, a repeat with the same key + body replays the original decision (24h). Analyze responses are not replayed.",
            "type": "string"
          },
          "preflight_mode": {
            "description": "REQUIRED. \"analyze\" = informational risk only (no decision/execution_action/safe_for_agent; analysis_outcome + may_execute:false). \"authorize\" = operation-bound path; may mint a receipt (requires context.operation). Decision Spec 2.0: omission is INVALID_INPUT. Do not pin 1.0 — that pin retired.",
            "enum": [
              "analyze",
              "authorize"
            ],
            "type": "string"
          },
          "previous_receipt": {
            "description": "Optional prior chain token to LINK this call into a receipt chain: base64url(body).base64url(signature). Linking is not verification — a linked token is not re-checked here; use verify_receipt.",
            "type": "string"
          },
          "response_detail": {
            "description": "How much of the response to return. control = the fields an agent branches on; standard = control + the human report and labelled break rows (the MCP default); full = everything (the REST default). Every value is copied from the full response.",
            "enum": [
              "control",
              "standard",
              "full"
            ],
            "type": "string"
          }
        },
        "required": [
          "preflight_mode"
        ],
        "then": {
          "properties": {
            "context": {
              "properties": {
                "operation": {
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "operation"
              ],
              "type": "object"
            }
          },
          "required": [
            "context"
          ]
        },
        "type": "object"
      },
      "name": "preflight_change_set"
    },
    {
      "description": "Verify a CodeRifts signed chain-receipt you ALREADY HOLD: cryptographic\nauthenticity (signature + key id), body binding, and — when lifecycle indices\nare available — whether it is currently valid authorization (not expired,\nsuperseded, or revoked) for a stated operation/target.\n\nUse this when:\n- You already obtained a chain_receipt / receipt token from a prior preflight\n  (or CI artifact) and are about to act (merge/deploy) under that receipt.\n- A contract-gate or policy requires offline/online proof that the receipt is\n  authentic for this change before proceeding.\n- You must distinguish \"signature ok\" from \"currently authorized\" (stale or\n  superseded receipts must not be treated as live approval).\n\nDo not use when:\n- You do not have a receipt yet — call coderifts.preflight_change_set first.\n- You need a NEW decision for a changed base→head set — preflight again;\n  verify_receipt does not re-diff specs.\n- The receipt you hold binds a different operation or target than the one you\n  are about to perform — call coderifts.preflight_change_set with\n  context.operation set to that operation (a merge receipt does not authorize\n  a deploy); verify_receipt cannot re-scope or re-issue a decision.\n- You only need human-readable history of an old decision_id without a receipt\n  token — use coderifts.get_decision_details.\n- The change set itself is unknown or incomplete — fix the change set and\n  preflight; do not \"verify\" a placeholder.\n\nInputs: receipt token (required); target_id = decision_result.artifact_digest — required\nfor an authorization verdict; omitted → target_not_stated. Optional intended context\n(operation, environment, fingerprint, audience, repository/branch/pull_request, base/head)\nand the body_hash-bound decision_result envelope. 30s clock-skew leeway on expiry. A 0s\ngrace for declared destructive production operations is defined in the policy but\nis unreachable today: the intended-context schema has no destructive field, so\nnothing can declare one and the 30s leeway always applies.\nReturns { valid, status, currently_authorized (bool|null), reason, payload, authz_* }.\nBranch on currently_authorized; null = not evaluated.\n\nWhen a decision envelope is also in hand (e.g. from a prior preflight), its\ncontrol_envelope.next_agent_step (if present) is structured remediation guidance\nthe agent MAY follow after a non-CONTINUE decision — still branch on\nexecution_action; next_agent_step is suggestion, not permission.",
      "inputSchema": {
        "description": "Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id set to decision_result.artifact_digest, audience, repository/branch/pull_request, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject.",
        "properties": {
          "audience": {
            "description": "Intended audience — must match the receipt",
            "type": "string"
          },
          "base": {
            "description": "Intended base commit/ref SHA the receipt must match (signed-wins vs envelope.base)",
            "type": "string"
          },
          "branch": {
            "description": "Intended branch the receipt must bind (place binding; optional)",
            "type": "string"
          },
          "decision_result": {
            "additionalProperties": true,
            "description": "The body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent. Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json.",
            "properties": {
              "audience": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "authority": {
                "description": "Additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL.",
                "type": [
                  "object",
                  "null"
                ]
              },
              "base": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "blast_radius": {
                "description": "Additive COUNTS (not a score). Not permission.",
                "properties": {
                  "consumers_declared": {
                    "minimum": 0,
                    "type": "integer"
                  },
                  "consumers_observed": {
                    "minimum": 0,
                    "type": "integer"
                  },
                  "endpoints": {
                    "minimum": 0,
                    "type": "integer"
                  },
                  "fields": {
                    "minimum": 0,
                    "type": "integer"
                  },
                  "graph_source": {
                    "type": "string"
                  },
                  "params": {
                    "minimum": 0,
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "decision": {
                "enum": [
                  "ALLOW",
                  "WARN",
                  "REQUIRE_APPROVAL",
                  "BLOCK"
                ],
                "type": "string"
              },
              "decision_body_hash": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "decision_id": {
                "type": "string"
              },
              "derivation": {
                "description": "Additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint.",
                "type": [
                  "object",
                  "null"
                ]
              },
              "environment": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "execution_action": {
                "enum": [
                  "CONTINUE",
                  "CONTINUE_WITH_MONITORING",
                  "REQUEST_APPROVAL",
                  "STOP"
                ],
                "type": "string"
              },
              "expires_at": {
                "type": "string"
              },
              "fingerprint": {
                "type": "string"
              },
              "head": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "input_fingerprint": {
                "type": "string"
              },
              "operation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "receipt": {
                "type": "object"
              },
              "repository": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "safe_for_agent": {
                "type": "boolean"
              },
              "spec_version": {
                "pattern": "^decision-result\\.v1(\\.[0-9]+)?$",
                "type": "string"
              }
            },
            "type": "object"
          },
          "environment": {
            "description": "Intended environment (e.g. production) — must match the receipt",
            "type": "string"
          },
          "fingerprint": {
            "description": "Intended change fingerprint — must equal the receipt fp",
            "type": "string"
          },
          "head": {
            "description": "Intended head commit/ref SHA the receipt must match (signed-wins vs envelope.head)",
            "type": "string"
          },
          "operation": {
            "description": "Intended operation the receipt must authorize (conventional: merge|deploy|tool_call|publish). Triggers authorization evaluation when non-empty; supply decision_result for full scope binding.",
            "type": "string"
          },
          "pull_request": {
            "description": "Intended pull-request id the receipt must bind (place binding; optional)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          },
          "repository": {
            "description": "Intended repository the receipt must bind (place binding; optional)",
            "type": "string"
          },
          "target_id": {
            "description": "REQUIRED to authorize under a held receipt. Set it to decision_result.artifact_digest — the digest of the artifact the receipt was issued for, which you already hold in the decision_result you are passing. The server does NOT derive it for you: it carries YOUR intended apply-site, and taking it from the envelope would compare that document against itself. Omit it and the answer is currently_authorized false with authz_reason target_not_stated and authz_status VERIFIED_TARGET_NOT_STATED — a missing input, distinct from target_mismatch, which means the receipt covers a different target.",
            "type": "string"
          },
          "token": {
            "description": "The chain receipt token (base64url(body).base64url(signature))",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "type": "object"
      },
      "name": "verify_receipt"
    }
  ]
}

What the leaf hashes

{"body":"84e01f1444eb47478d512e6b3655e6e3370ebc7aba2d574976f725cc234113f7","id":579508,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793143473401558,"prev":null,"subject":"63358b21-79a0-4bc8-97f1-b958c169084b","subject_kind":"endpoint"}

Proof

Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (273461 rows).

  1. 0x9e8e22cb1f5aade3ffa79d6ab3c0a63c62b53f225bce1ec170e5eee7136e5206
  2. 0x550fca2ee7174162821c49d8f3e080dbc6862ebc48ef1dfbdb1426f35685091c
  3. 0x4380a09b8a04f31a705cf9cc9baff43ce79094e19cf08667cf8a494a7433133a
  4. 0x8930026614b124497710ae2892d5c8ebb05dad1c8e12ddbe833d54402bd645a0
  5. 0xbe3a68626e594230ea4942325945e897063a68b8e568f7d1458b69a7b3806b96
  6. 0x117b06e709e51c6f68fcf1cfc6ff65f3dc37ce046f07eb4503543a03574d0172
  7. 0x43c1035070215cb8e418bf1256a8f288c88bb1f09e4eee7d67532cfd0988ea03
  8. 0xa4d82646592870aa6d96381746d2af33e0d6256791b7b7c5f8d2dc9b1b14de6f
  9. 0x217e8febbf10e5374c252bf5ed797554272a6919be2a757faf8681258be8424c
  10. 0x3661fc103f9e8ae5a55d05dfa93995ef65fee8ded3bc01a5e72ec06886163e17
  11. 0xb1ccf28ab1a7fa316a090ec87291371439da179c523f84e00e64a6628e44fced
  12. 0x121ffc8b387c54931bc53056e106d9ada0e2f7c1d32ebc819c3306406c952295
  13. 0xa91c23113464e2fc1e93d41e407b7c6c254bee2eac2f7a550e2f9a1275eef26a
  14. 0xb37e6165108af3c1962db6b76953aee5ee86201747a07444ad2760bf2d5dca23
  15. 0xa3fff4662cd48659f5bafd0612931759a90e53a7b4209ed8f26f6594a07bb547
  16. 0x64c405a28e8819716221eb2529fe4ce277ab08025e17e685cbd5ece75ceb75c7
  17. 0xf30fddbf4811226c58e8f0daf36fddd79fc5f1356b592bb1d99a8061ddbabe66
  18. 0x2bf8151e5f157dd183b9de6fa00469551932a7a6e3f33a694895000ac9061197
  19. 0x9fc354c0ea3efc3f1b6548bb77ea902a50f2c9647647ea61592efce2bd795699
Day root
0xdd77e5e99da32c3f154180d63e3c3e6fe11e896a2c6896412ef6b5c4bcf7e795
Chained
0x23bb4dfd09f55c15ac3962f53578e02c6114d5bfd9bb451cf8794fb6e2817ef4
Published
On Arc Testnet, block 69414147: 0xb2ebd83aafeb765a0ce66e76aefb133ed06606c98038fd56191e2bcd1dcb77b4

How to check it · This row as JSON