Protocol · Organization eligibility

Private organization and authorized-signer eligibility

Abraxas returns a narrow audience-bound organization or authorized-signer result. Partners apply their own wallet governance, AML/KYT, quorum, and transaction rules. This is not document collection, a company database, sanctions screening, custody, or a live Utila integration.

What this is

A wallet-control proof alone can never qualify as KYB or authorized-signer evidence.

Utila-compatible private result shapes only. There is no live Utila API, wallet product, AML/KYT, quorum, or transaction-policy integration.

Reviewed policy contracts

  • organization_eligible — minimum privacy_preserving L2. Not self-publishable. Not automatically active.
  • authorized_signer — minimum privacy_preserving L2. Not self-publishable. Not automatically active.
  • jurisdiction_eligible — minimum privacy_preserving L2. Not self-publishable. Not automatically active.
  • institutional_counterparty_eligible — minimum privacy_preserving L2. Not self-publishable. Not automatically active.

Catalog path is Policy Proposal → Release Candidate → reviewed source change. Missing reviewed issuer mapping fails closed. Reclaim stays sandbox or integration-ready until a reviewed organization provider mapping exists.

Client-visible result fields

schema_version, organization_ref, actor_ref, result_category, result, currently_valid, policy_id, policy_version, action, action_scope, environment, audience_hash, issued_at, expires_at, subject_binding_hash, selective_disclosure_summary

Migration

DEMO-first file 106_private_organization_eligibility.sql. Apply in the DEMO SQL editor only: https://supabase.com/dashboard/project/ocntwbxarpjeixdnzide/sql/new. Do not auto-apply.

Server example

import { AbraxasPartnerKit } from "@abraxas/partner-kit";

const kit = new AbraxasPartnerKit({
  partnerId: process.env.ABRAXAS_PARTNER_ID,
  policyId: process.env.ABRAXAS_POLICY_ID,
  policyVersion: Number(process.env.ABRAXAS_POLICY_VERSION),
  requirePolicyVersion: true,
  environment: "sandbox",
  baseUrl: process.env.ABRAXAS_BASE_URL,
});

export async function requestInstitutionalEligibilityGate(nonce) {
  const consent = await fetch(process.env.ABRAXAS_BASE_URL + "/api/v1/organization-eligibility/consent", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      authorization: "Bearer " + process.env.ABRAXAS_SANDBOX_API_KEY,
    },
    body: JSON.stringify({
      result_category: "authorized_signer",
      purpose: "Confirm one named protocol action",
      action: "enable_protocol_access",
      action_scope: "sandbox:protocol_access",
      environment: "sandbox",
    }),
  }).then((res) => res.json());

  const issued = await fetch(process.env.ABRAXAS_BASE_URL + "/api/v1/organization-eligibility/issue", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      authorization: "Bearer " + process.env.ABRAXAS_SANDBOX_API_KEY,
    },
    body: JSON.stringify({ consent_ref: consent.consent_ref }),
  }).then((res) => res.json());

  // issued.result is authorized_signer: approved | denied | expired | revoked.
  // Re-fetch the current public receipt before any grant. This is not KYB evidence.
  const receipt = await kit.fetchPublicReceipt(process.env.ABRAXAS_RECEIPT_ID);
  if (!receipt.ok) return { allowed: false };
  return { ...issued, presentation_sufficient: false, utila_integration: false };
}

export async function issueInstitutionalChainAttestation(receiptId) {
  const res = await fetch(process.env.ABRAXAS_BASE_URL + "/api/v1/chain-attestations", {
    method: "POST",
    headers: {
      authorization: "Bearer " + process.env.ABRAXAS_SANDBOX_API_KEY,
      "content-type": "application/json",
    },
    body: JSON.stringify({
      receipt_id: receiptId,
      action_type: "enable_protocol_access",
      action_scope: "sandbox:protocol_access",
      network_id: "evm_sandbox",
      deployment_ref: process.env.ABRAXAS_GATE_DEPLOYMENT_REF,
    }),
  });
  return res.json();
}