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
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
// 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:
{
"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:
// 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.Authorizationis your Ekayana session token;X-Dataverse-Tokenis your own Dataverse API token, which the platform never stores.X-Dataverse-Serverselects the installation (defaults todemo).
Publish Dataset
// 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
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:
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
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 Role | Dataverse Role | Permissions |
|---|---|---|
owner | Admin | Full control |
contributor | Contributor | Add/edit files |
curator | Curator | Edit metadata |
viewer | File Downloader | Download 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.