Documentation

Dataverse Integration

No research platform gets to start from zero. Datasets already live in Dataverse installations, carry DOIs, and are cited by papers that will never be updated - any system that asks researchers to abandon that is dead on arrival. So Bio-DID-Seq bridges instead: a dataset keeps its Dataverse record and its DOI, and gains a DID, IPFS-addressed storage, and AI-enriched metadata alongside them.

Concretely, the bridge gives you bidirectional sync between IPFS and Dataverse, a persistent DID-to-DOI mapping, BioAgents enrichment of Dataverse metadata, privacy controls that hold across both systems, and provenance you can verify by hash rather than by trusting a changelog.

Configuration

typescript
export const dataverseConfig = {
  serverUrl: process.env.DATAVERSE_URL || 'https://dataverse.harvard.edu',
  apiToken: process.env.DATAVERSE_API_TOKEN,
  defaultDataverse: process.env.DATAVERSE_ALIAS || 'bio-did-seq',
  sync: {
    enabled: true,
    interval: '1h',
    conflictResolution: 'latest-wins'
  }
};

API Reference

Create Dataset

typescript
// POST /api/dataverse/dataset
const response = await fetch('/api/dataverse/dataset', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    did: 'did:bio:123456789abcdefghi',
    dataverseAlias: 'research-lab',
    metadata: {
      title: 'CRISPR-Cas9 Gene Editing Dataset',
      authors: [{ name: 'Jane Smith', orcid: '0000-0001-2345-6789' }],
      description: 'Comprehensive dataset from CRISPR experiments...',
      keywords: ['CRISPR', 'gene editing', 'genomics'],
      license: 'CC-BY-4.0'
    }
  })
});

Response:

json
{
  "success": true,
  "data": {
    "datasetId": 12345,
    "persistentId": "doi:10.7910/DVN/EXAMPLE",
    "did": "did:bio:123456789abcdefghi",
    "status": "DRAFT",
    "links": {
      "dataverse": "https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/EXAMPLE",
      "ipfs": "ipfs://QmXg9Pp2ytZ14xgK35M6iTC2Vz6jR9zYgooNp2UHPTMnPN"
    }
  }
}

Upload Files

The dataset's persistent identifier (its DOI) is part of the path, and the multipart body carries the file plus an optional description:

typescript
// POST /api/dataverse/dataset/file/{persistent_id}
const formData = new FormData();
formData.append('file', file);
formData.append('description', 'Raw sequencing reads');

const persistentId = encodeURIComponent('doi:10.70122/FK2/ABCDEF');

const response = await fetch(
  `/api/dataverse/dataset/file/${persistentId}`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'X-Dataverse-Token': dataverseApiToken,
      'X-Dataverse-Server': 'demo',
    },
    body: formData,
  }
);
Two credentials. Authorization is your Ekayana session token; X-Dataverse-Token is your own Dataverse API token, which the platform never stores. X-Dataverse-Server selects the installation (defaults to demo).

Publish Dataset

typescript
// POST /api/dataverse/dataset/publish
const response = await fetch('/api/dataverse/dataset/publish', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    datasetId: 'doi:10.7910/DVN/EXAMPLE',
    did: 'did:bio:123456789abcdefghi',
    type: 'major',
    updateIPNS: true
  })
});

Link DID to Dataverse DOI

bash
curl -X POST "https://api.ekayana.com/api/did/did:bio:123456789/dataverse" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "dataverseDoi": "doi:10.7910/DVN/EXAMPLE",
    "syncMetadata": true,
    "createIPNS": true
  }'

BioAgents Enhancement

When uploading files, BioAgents can automatically extract and enhance metadata:

typescript
async function uploadWithEnhancement(file: File, persistentId: string) {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('description', 'Deposited via Ekayana');

  const response = await fetch(
    `/api/dataverse/dataset/file/${encodeURIComponent(persistentId)}`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'X-Dataverse-Token': dataverseApiToken,
      },
      body: formData,
    }
  );

  return response.json();
}
Metadata extraction and knowledge graph enrichment run through the BioAgents endpoints as a separate step, not as flags on the deposit call.

Access Control

UCAN-Based Permissions

typescript
async function grantDataverseAccess(
  issuerKeypair: ed25519.EdKeypair,
  recipientDID: string,
  datasetDID: string,
  permissions: ('read' | 'write' | 'admin')[]
) {
  const ucan = await build({
    issuer: issuerKeypair,
    audience: recipientDID,
    lifetimeInSeconds: 30 * 24 * 3600,
    capabilities: permissions.map(p => ({
      with: { scheme: 'did', hierPart: datasetDID },
      can: { namespace: 'dataverse', segments: [p] }
    }))
  });
  
  return encode(ucan);
}

Role Mapping

Bio-DID-Seq RoleDataverse RolePermissions
ownerAdminFull control
contributorContributorAdd/edit files
curatorCuratorEdit metadata
viewerFile DownloaderDownload files

Habits worth forming

Link every DID to its DOI - discoverability should work from either direction, and the link is cheap. Turn on automatic sync for datasets that still change. Run papers through BioAgents at deposit time, while the metadata context is fresh. Keep the IPFS copy pinned even for data that "lives" in Dataverse; it's the backup that doesn't depend on any one institution's uptime. And put an IPNS record in front of any dataset you expect to revise, so citations to old versions and readers of new ones both stay happy.