The biosampleDetails page (https://genobank.io/laboratories/profile/biosampleDetails/?biosampleSerial={serial}
) is a critical interface for viewing comprehensive information about genomic biosamples, including blockchain records, Story Protocol IP assets, and associated files.
https://genobank.io/laboratories/profile/biosampleDetails/?biosampleSerial=41230711101565
/laboratories/profile/biosampleDetails/
biosampleSerial
- The unique serial number of the biosample/laboratories/profile/biosampleDetails/
├── index.html # Main HTML template
├── custom.js # Core page logic and data rendering
├── service.js # API service layer
├── components.js # Reusable UI components
├── ancestry-chart.js # Ancestry visualization
├── aiDescriptoFunctions.js # AI descriptor integration
└── css/
└── style.css # Page-specific styles
graph TD
A[User visits biosampleDetails page] --> B[index.html loads]
B --> C[Load JS dependencies]
C --> D[custom.js initializes]
D --> E[Extract biosampleSerial from URL]
E --> F[Check user authentication]
F --> G[Fetch biosample data]
G --> H[Render biosample details]
H --> I[Display Story Protocol data if available]
// service.js - API call to fetch biosample data
GET https://genobank.app/biosample_details_proxy?biosample_serial={serial}&requester_serial={userSerial}
// Response format
{
serial: 41230711101565,
owner: "0xbba236F126D40DF943C9Fa90593477f55C50b2A1",
status: "ACTIVE",
chainID: 43113,
tokenId: "0x257fc5e3980000...",
txHash: "0xb45d25dc259b9ffe...",
delivered: true,
story_record: {
ip_asset_id: "0x...",
tx_hash: "0x...",
tx_link: "https://explorer.story.foundation/tx/...",
token_id: 1,
created_date: "2024-09-03",
// Additional metadata fields...
},
file_names: ["file1.vcf", "file2.txt"],
profile: {
text: '{"name": "Lab Name", "investigator": "Dr. Smith"}'
}
}
custom.js
)async function pageLoaded(biosampleSerial) {
if (isLoggedIn()) {
const user_address = getUserWallet();
// Fetch user balance and permittee status
const isPermittee = isCurrentUserPermittee();
if (isPermittee) {
userSerial = await getPermitteeSerialByAddress(user_address);
}
}
await renderBiosampleDetails(biosampleSerial);
}
service.js
)async function getBiosampleDetails(biosampleSerial, requester_serial) {
const url = new URL(`${window.NEW_API_BASE}/biosample_details_proxy`);
url.searchParams.append('biosample_serial', biosampleSerial);
url.searchParams.append('requester_serial', requester_serial || 0);
const response = await fetch(url);
return response.json();
}
custom.js
)The page dynamically displays Story Protocol IP asset information when available:
if (!isEmpty(biosample?.story_record)) {
$("#story-record-section").show();
// Display IP Asset ID with link to explorer
$("#id-ip-asset-id").html(`
<a href="https://explorer.story.foundation/ipa/${biosample.story_record.ip_asset_id}">
${biosample.story_record.ip_asset_id}
</a>
`);
// Display transaction hash
$("#id-ip-asset-transaction").html(`
<a href="${biosample.story_record.tx_link}">
${biosample.story_record.tx_hash}
</a>
`);
// Display additional metadata if provided by API
// - NFT image
// - Collection info
// - License terms
// - Token ID
// - Creation date
}
The page implements comprehensive error handling:
story_record: {
ip_asset_id: string, // IP Asset address
tx_hash: string, // Transaction hash
tx_link: string, // Explorer link
token_id: number, // NFT token ID
created_date: string, // Creation date
nft_image_url: string, // NFT image URL (optional)
collection_address: string, // Collection contract (optional)
collection_name: string, // Collection name (optional)
license_terms: { // License details (optional)
license_type: string,
commercial_use: boolean,
derivatives_allowed: boolean,
attribution_required: boolean
},
ipfs_metadata_url: string, // IPFS metadata link (optional)
file_size: string // File size (optional)
}
The page uses environment detection from /js/env.js
:
window.NEW_API_BASE = "https://genobank.app" // Production
window.WWW_BASE = "https://genobank.io" // Frontend base
Symptom: API returns {}
Cause: Biosample not activated or doesn’t exist
Solution: Activate biosample through proper channels
Symptom: Section hidden despite biosample having Story data Cause: API not returning story_record field Solution: Check API response includes story_record data
Symptom: Page keeps redirecting to login Cause: Invalid or expired Web3 signature Solution: Clear localStorage and re-authenticate