A TypeScript SDK for the Originals Protocol - enabling creation, discovery, and transfer of digital assets with cryptographically verifiable provenance.
The Originals Protocol organizes digital asset lifecycles into three layers:
did:peer- Private creation and experimentation (offline, free)did:webvh- Public discovery via HTTPS hosting ($25/year)did:btco- Transferable ownership on Bitcoin ($75-200 one-time)
Assets migrate unidirectionally through these layers, with economic gravity determining when Bitcoin-level security is justified.
npm install @originals/sdkimport { OriginalsSDK, OrdMockProvider } from '@originals/sdk';
// For testing/development - use mock provider
const originals = OriginalsSDK.create({
network: 'testnet',
enableLogging: true,
ordinalsProvider: new OrdMockProvider()
});
// Create a digital asset
const resources = [{
id: 'my-artwork',
type: 'image',
contentType: 'image/png',
hash: 'sha256-hash-of-content'
}];
const asset = await originals.lifecycle.createAsset(resources);
// Publish for discovery
await originals.lifecycle.publishToWeb(asset, 'my-domain.com');
// Inscribe on Bitcoin for permanent ownership
await originals.lifecycle.inscribeOnBitcoin(asset);- OriginalsSDK - Main entry point and orchestration
- OriginalsAsset - Represents a digital asset through its lifecycle
- DIDManager - DID document creation and resolution (did:peer, did:webvh, did:btco) with external signer support
- CredentialManager - Verifiable Credential handling
- LifecycleManager - Asset migration between layers
- BitcoinManager - Bitcoin/Ordinals integration
- ✅ W3C DID and Verifiable Credential compliance
- ✅ Multibase key encoding (no JSON Web Keys)
- ✅ JSON-LD credential signing (no JWT)
- ✅ Bitcoin Ordinals inscription support
- ✅ Three-layer asset lifecycle management:
did:peer→did:webvh→did:btco - ✅ Cryptographic provenance verification
- ✅ Front-running protection via unique satoshi assignment
- ✅ DID:WebVH integration with didwebvh-ts - Full support for creating and managing did:webvh identifiers
- ✅ External signer support - Integrate with Turnkey, AWS KMS, HSMs, and other key management systems
Artists create private assets for experimentation, publish for discovery, and inscribe on Bitcoin upon sale.
Researchers document datasets privately, publish for peer review, and anchor provenance on Bitcoin for permanent record.
Issue member credentials privately, make public for recognition, and inscribe key decisions for immutable governance record.
Manufacturers create product credentials, publish public registries, and inscribe final ownership for anti-counterfeiting.
Bitcoin operations (inscribing and transferring) require an ordinalsProvider to be configured. The SDK provides several options:
For testing and local development, use the built-in mock provider:
import { OriginalsSDK, OrdMockProvider } from '@originals/sdk';
const sdk = OriginalsSDK.create({
network: 'regtest',
ordinalsProvider: new OrdMockProvider()
});Mainnet (Production):
import { OrdinalsClient } from '@originals/sdk';
const sdk = OriginalsSDK.create({
network: 'mainnet',
ordinalsProvider: new OrdinalsClient({
network: 'mainnet',
apiUrl: 'https://your-ord-api.com',
walletPrivateKey: process.env.BITCOIN_PRIVATE_KEY
})
});Testnet:
const sdk = OriginalsSDK.create({
network: 'testnet',
ordinalsProvider: new OrdinalsClient({
network: 'testnet',
apiUrl: 'https://testnet.ord-api.com',
walletPrivateKey: process.env.TESTNET_PRIVATE_KEY
})
});Signet:
const sdk = OriginalsSDK.create({
network: 'signet',
ordinalsProvider: new OrdinalsClient({
network: 'signet',
apiUrl: 'https://signet.ord-api.com',
walletPrivateKey: process.env.SIGNET_PRIVATE_KEY
})
});Optionally configure a fee oracle for dynamic fee estimation:
const sdk = OriginalsSDK.create({
network: 'mainnet',
ordinalsProvider: new OrdinalsClient({...}),
feeOracle: {
estimateFeeRate: async (targetBlocks: number) => {
// Fetch current fee rates from your preferred source
const response = await fetch('https://mempool.space/api/v1/fees/recommended');
const fees = await response.json();
return targetBlocks <= 1 ? fees.fastestFee : fees.halfHourFee;
}
}
});If you attempt Bitcoin operations without configuring an ordinalsProvider, you'll receive a clear error:
const sdk = OriginalsSDK.create({ network: 'mainnet' });
// This will throw StructuredError with code 'ORD_PROVIDER_REQUIRED'
await sdk.bitcoin.inscribeData(data, 'application/json');
// Error: Ordinals provider must be configured to inscribe data on Bitcoin.
// Please provide an ordinalsProvider in your SDK configuration.You can also validate the configuration before attempting operations:
try {
sdk.validateBitcoinConfig();
// Safe to perform Bitcoin operations
} catch (error) {
console.error('Bitcoin operations not available:', error.message);
}The SDK provides comprehensive support for creating and managing did:webvh identifiers with proper cryptographic signing.
const sdk = OriginalsSDK.create({ network: 'mainnet' });
const result = await sdk.did.createDIDWebVH({
domain: 'example.com',
paths: ['alice'],
outputDir: './public/.well-known',
});
console.log('DID:', result.did);
// Store result.keyPair.privateKey securely!import { createTurnkeySigner } from './turnkey-signer';
// Create external signer
const signer = await createTurnkeySigner(subOrgId, keyId, turnkeyClient, verificationMethodId, publicKeyMultibase);
// Create DID
const result = await sdk.did.createDIDWebVH({
domain: 'example.com',
paths: ['alice'],
externalSigner: signer,
verificationMethods: [{ type: 'Multikey', publicKeyMultibase: '...' }],
updateKeys: ['did:key:...'],
outputDir: './public/.well-known',
});const log = await sdk.did.loadDIDLog('./path/to/did.jsonl');
const result = await sdk.did.updateDIDWebVH({
did: 'did:webvh:example.com:alice',
currentLog: log,
updates: {
service: [{ id: '#my-service', type: 'MyService', serviceEndpoint: 'https://...' }]
},
signer: keyPair, // or externalSigner
});For detailed information about the DID:WebVH integration, including Turnkey setup and external signer implementation, see DIDWEBVH_INTEGRATION.md.
If you're an AI/LLM agent working with this SDK, we provide optimized documentation:
- docs/LLM_AGENT_GUIDE.md - Comprehensive API reference with complete type signatures, method documentation, and working examples
- docs/LLM_QUICK_REFERENCE.md - Compact quick-reference card for rapid lookups
- CLAUDE.md - Development context and project architecture
- docs/BITCOIN_INTEGRATION_GUIDE.md - Complete guide for Bitcoin integration
- docs/BITCOIN_API_REFERENCE.md - Bitcoin API reference
- docs/BITCOIN_BEST_PRACTICES.md - Best practices for production deployments
- docs/BITCOIN_TROUBLESHOOTING.md - Troubleshooting common issues
This is a monorepo managed with Turborepo for efficient task orchestration.
# Install dependencies
bun install
# Build all packages (SDK + Apps)
bun run build
# Test all packages
bun test
# Lint all packages
bun run lint
# Start development servers
bun run dev
# Type check all packages
bun run checksdk/
├── packages/
│ └── sdk/ # Main SDK package
└── apps/
└── originals-explorer/ # Explorer application
- Intelligent caching: Never rebuild the same code twice
- Parallel execution: Run tasks across packages simultaneously
- Task dependencies: Automatically build dependencies before dependents
For detailed information about using Turborepo, see docs/TURBOREPO.md.
MIT License - see LICENSE file for details.