Core payload modeling capabilities for the XYO Protocol 2.0 ecosystem, offering TypeScript interfaces and types for defining, validating, and manipulating payloads within the XYO blockchain network.
Hash-based and sequence-based metadata system for tracking payloads in blockchain storage, including data hash tracking, storage hash management, and sequence parsing for temporal ordering in the XYO network.
Complete storage metadata combining hash and sequence information for comprehensive payload tracking.
/**
* Import Hash type from @xylabs/hex
*/
import type { Hash } from '@xylabs/hex';
/**
* Complete storage metadata interface combining hash and sequence tracking
*/
interface StorageMeta extends SequenceStorageMeta, HashStorageMeta {
_hash: Hash;
_dataHash: Hash;
_sequence: Sequence;
}
/**
* Add storage metadata to payload type
*/
type WithStorageMeta<T extends Payload = Payload> = T & StorageMeta;
/**
* Add partial storage metadata to payload type
*/
type WithPartialStorageMeta<T extends Payload = Payload> = T & Partial<StorageMeta>;
/**
* Type guard for complete storage metadata
*/
function isStorageMeta(value: unknown): value is StorageMeta;
/**
* Type assertion for storage metadata
*/
function asStorageMeta(value: unknown): StorageMeta;
/**
* Optional type assertion for storage metadata
*/
function asOptionalStorageMeta(value: unknown): StorageMeta | undefined;Usage Examples:
import {
StorageMeta,
WithStorageMeta,
isStorageMeta,
Payload
} from "@xyo-network/payload-model";
// Payload with complete storage metadata
interface UserPayloadWithStorage extends WithStorageMeta<Payload> {
schema: "network.example.user";
name: string;
email: string;
}
const userWithStorage: UserPayloadWithStorage = {
schema: "network.example.user",
name: "Alice",
email: "alice@example.com",
_hash: "0x123...",
_dataHash: "0x456...",
_sequence: "1234567890abcdef"
};
// Validate storage metadata
if (isStorageMeta(userWithStorage)) {
console.log("Hash:", userWithStorage._hash);
console.log("Data Hash:", userWithStorage._dataHash);
console.log("Sequence:", userWithStorage._sequence);
}
// Process payloads with storage metadata
function processStoredPayload(payload: WithStorageMeta<Payload>) {
return {
schema: payload.schema,
hash: payload._hash,
dataHash: payload._dataHash,
sequence: payload._sequence
};
}Hash-based tracking system for payload storage including both content hash and storage hash.
/**
* Data hash storage metadata
*/
interface DataHashStorageMeta {
_dataHash: Hash;
}
/**
* Complete hash storage metadata extending data hash with storage hash
*/
interface HashStorageMeta extends DataHashStorageMeta {
_hash: Hash;
_dataHash: Hash;
}
/**
* Add data hash metadata to payload type
*/
type WithDataHashStorageMeta<T extends Payload = Payload> = T & DataHashStorageMeta;
/**
* Add hash metadata to payload type
*/
type WithHashStorageMeta<T extends Payload = Payload> = T & HashStorageMeta;
/**
* Type guard for data hash metadata
*/
function isDataHashStorageMeta(value: unknown): value is DataHashStorageMeta;
/**
* Type guard for complete hash metadata
*/
function isHashStorageMeta(value: unknown): value is HashStorageMeta;
/**
* Type assertion for data hash metadata
*/
function asDataHashStorageMeta(value: unknown): DataHashStorageMeta;
/**
* Type assertion for hash metadata
*/
function asHashStorageMeta(value: unknown): HashStorageMeta;Usage Examples:
import {
HashStorageMeta,
DataHashStorageMeta,
WithHashStorageMeta,
isHashStorageMeta,
isDataHashStorageMeta
} from "@xyo-network/payload-model";
// Payload with hash metadata
interface TrackedPayload extends WithHashStorageMeta<Payload> {
schema: "network.example.tracked";
data: string;
}
const trackedPayload: TrackedPayload = {
schema: "network.example.tracked",
data: "important data",
_hash: "0x789...", // Storage hash
_dataHash: "0xabc..." // Content hash
};
// Validate hash metadata
if (isHashStorageMeta(trackedPayload)) {
console.log("Storage hash:", trackedPayload._hash);
console.log("Content hash:", trackedPayload._dataHash);
}
// Check for data hash only
const partialPayload = {
schema: "network.example.partial",
data: "some data",
_dataHash: "0xdef..."
};
if (isDataHashStorageMeta(partialPayload)) {
console.log("Has data hash:", partialPayload._dataHash);
}Sequence-based metadata for temporal ordering and tracking in the XYO network.
/**
* Sequence storage metadata
*/
interface SequenceStorageMeta {
_sequence: Sequence;
}
/**
* Add sequence metadata to payload type
*/
type WithSequenceStorageMeta<T extends Payload = Payload> = T & SequenceStorageMeta;
/**
* Type guard for sequence metadata
*/
function isSequenceStorageMeta(value: unknown): value is SequenceStorageMeta;
/**
* Type assertion for sequence metadata
*/
function asSequenceStorageMeta(value: unknown): SequenceStorageMeta;
/**
* Optional type assertion for sequence metadata
*/
function asOptionalSequenceStorageMeta(value: unknown): SequenceStorageMeta | undefined;Comprehensive sequence type system with local and qualified sequences for XYO network ordering.
/**
* Import types from @xylabs/hex for branded hex types
*/
import type { Address, Brand, Hex } from '@xylabs/hex';
/**
* Local sequence type (epoch + nonce)
*/
type LocalSequence = Brand<Hex, { __localSequence: true }>;
/**
* Qualified sequence type (local sequence + address)
*/
type QualifiedSequence = Brand<Hex, { __qualifiedSequence: true }>;
/**
* Union of local and qualified sequences
*/
type Sequence = LocalSequence | QualifiedSequence;
/**
* Epoch component of sequence
*/
type Epoch = Brand<Hex, { __epoch: true }>;
/**
* Nonce component of sequence
*/
type Nonce = Brand<Hex, { __nonce: true }>;
/**
* Type guard for epoch
*/
function isEpoch(value: unknown): value is Epoch;
/**
* Type guard for nonce
*/
function isNonce(value: unknown): value is Nonce;
/**
* Type guard for local sequence
*/
function isLocalSequence(value: unknown): value is LocalSequence;
/**
* Type guard for qualified sequence
*/
function isQualifiedSequence(value: unknown): value is QualifiedSequence;
/**
* Type guard for any sequence type
*/
function isSequence(value: unknown): value is Sequence;
/**
* Constants for sequence component lengths and limits
*/
const SequenceConstants: {
// Component lengths in bytes
epochBytes: 8;
nonceBytes: 8;
nonceIndexBytes: 4;
nonceHashBytes: 4;
addressBytes: 20;
localSequenceBytes: 16; // epochBytes + nonceBytes
qualifiedSequenceBytes: 36; // localSequenceBytes + addressBytes
// Min/max values for components
minEpoch: Epoch;
maxEpoch: Epoch;
minNonce: Nonce;
maxNonce: Nonce;
minAddress: Address;
maxAddress: Address;
minLocalSequence: LocalSequence;
maxLocalSequence: LocalSequence;
minQualifiedSequence: QualifiedSequence;
maxQualifiedSequence: QualifiedSequence;
};
/**
* Local sequence specific constants
*/
const LocalSequenceConstants: typeof SequenceConstants & {
localSequenceBytes: 16;
minLocalSequence: LocalSequence;
maxLocalSequence: LocalSequence;
};
/**
* Qualified sequence specific constants
*/
const QualifiedSequenceConstants: {
qualifiedSequenceBytes: 36;
minQualifiedSequence: QualifiedSequence;
maxQualifiedSequence: QualifiedSequence;
};Usage Examples:
import {
Sequence,
LocalSequence,
QualifiedSequence,
isSequence,
isLocalSequence,
isQualifiedSequence,
SequenceConstants
} from "@xyo-network/payload-model";
// Work with different sequence types
const localSeq: LocalSequence = "1234567890abcdef12345678" as LocalSequence;
const qualifiedSeq: QualifiedSequence = "1234567890abcdef12345678901234567890abcdef12345678901234567890abcdef" as QualifiedSequence;
// Validate sequence types
function processSequence(seq: unknown) {
if (isLocalSequence(seq)) {
console.log("Local sequence:", seq);
} else if (isQualifiedSequence(seq)) {
console.log("Qualified sequence:", seq);
} else if (isSequence(seq)) {
console.log("Unknown sequence type:", seq);
} else {
console.log("Not a sequence");
}
}
// Use sequence constants
console.log("Local sequence bytes:", SequenceConstants.localSequenceBytes);
console.log("Qualified sequence bytes:", SequenceConstants.qualifiedSequenceBytes);
console.log("Min local sequence:", SequenceConstants.minLocalSequence);Advanced sequence parsing and manipulation utilities for extracting components and creating sequences.
/**
* Sequence parser class for extracting and manipulating sequence components
*/
class SequenceParser {
/**
* Create parser from existing sequence
*/
static from(sequence: Sequence, address?: Address): SequenceParser;
/**
* Create parser from timestamp and hash components
*/
static from(timestamp: Hex, hash: Hash, address?: Address): SequenceParser;
static from(timestamp: Hex, hash: Hex, address?: Address): SequenceParser;
static from(timestamp: Hex, nonce: Nonce, address?: Address): SequenceParser;
static from(timestamp: number, hash: Hash, address?: Address): SequenceParser;
static from(timestamp: number, hash: Hex, address?: Address): SequenceParser;
static from(timestamp: number, nonce: Nonce, address?: Address): SequenceParser;
/**
* Create parser from timestamp, hash, and index components
*/
static from(timestamp: Hex, hash: Hash, index?: number, address?: Address): SequenceParser;
static from(timestamp: Hex, hash: Hex, index?: number, address?: Address): SequenceParser;
static from(timestamp: Hex, nonce: Nonce, index?: number, address?: Address): SequenceParser;
static from(timestamp: number, hash: Hash, index?: number, address?: Address): SequenceParser;
static from(timestamp: number, hash: Hex, index?: number, address?: Address): SequenceParser;
static from(timestamp: number, nonce: Nonce, index?: number, address?: Address): SequenceParser;
/**
* Parse sequence from hex, string, or ArrayBuffer
*/
static parse(value: Hex | string | ArrayBufferLike): SequenceParser;
/**
* Convert value to epoch component
*/
static toEpoch(value: number | Hex | Epoch): Epoch;
/**
* Convert value to nonce component
*/
static toNonce(value: Hash | Hex, index?: number): Nonce;
/**
* Extract address component from qualified sequence
*/
get address(): Address;
/**
* Extract epoch component
*/
get epoch(): Epoch;
/**
* Extract local sequence (epoch + nonce)
*/
get localSequence(): LocalSequence;
/**
* Extract nonce component
*/
get nonce(): Nonce;
/**
* Extract qualified sequence (epoch + nonce + address)
*/
get qualifiedSequence(): QualifiedSequence;
}Usage Examples:
import { SequenceParser } from "@xyo-network/payload-model";
// Create sequence from timestamp and hash
const timestamp = Date.now();
const hash = "0x123456789abcdef";
const address = "0x742d35Cc6065C6EaABf23bA0aC21e0017E3BB26C";
const parser = SequenceParser.from(timestamp, hash, address);
// Extract components
console.log("Epoch:", parser.epoch);
console.log("Nonce:", parser.nonce);
console.log("Address:", parser.address);
console.log("Local Sequence:", parser.localSequence);
console.log("Qualified Sequence:", parser.qualifiedSequence);
// Parse existing sequence
const existingSequence = "1234567890abcdef12345678901234567890abcdef12345678901234567890abcdef";
const existingParser = SequenceParser.parse(existingSequence);
console.log("Parsed epoch:", existingParser.epoch);
console.log("Parsed nonce:", existingParser.nonce);
// Create epoch and nonce utilities
const epoch = SequenceParser.toEpoch(timestamp);
const nonce = SequenceParser.toNonce(hash, 0);
console.log("Created epoch:", epoch);
console.log("Created nonce:", nonce);Utilities for comparing and ordering sequences in the XYO network.
/**
* Sequence comparison utilities
*/
const SequenceComparer: {
/**
* Compare sequences by local sequence component only
*/
local: (a: Sequence, b: Sequence) => number;
/**
* Compare sequences by qualified sequence (includes address)
*/
qualified: (a: Sequence, b: Sequence) => number;
};Usage Examples:
import { SequenceComparer, Sequence } from "@xyo-network/payload-model";
const sequences: Sequence[] = [
"1234567890abcdef12345678" as Sequence,
"2345678901bcdef123456789" as Sequence,
"0123456789abcdef12345678" as Sequence
];
// Sort by local sequence
const sortedByLocal = sequences.sort(SequenceComparer.local);
console.log("Sorted by local:", sortedByLocal);
// Sort by qualified sequence
const qualifiedSequences: Sequence[] = [
"1234567890abcdef12345678901234567890abcdef12345678901234567890abcdef" as Sequence,
"2345678901bcdef123456789012345678901bcdef123456789012345678901bcdef1" as Sequence
];
const sortedByQualified = qualifiedSequences.sort(SequenceComparer.qualified);
console.log("Sorted by qualified:", sortedByQualified);
// Use in payload sorting
interface PayloadWithSequence {
schema: string;
data: any;
_sequence: Sequence;
}
function sortPayloadsBySequence(payloads: PayloadWithSequence[]) {
return payloads.sort((a, b) => SequenceComparer.local(a._sequence, b._sequence));
}Runtime validation schemas for storage metadata using Zod integration.
/**
* Zod schema for storage metadata validation
*/
const StorageMetaZod: ZodType<{
_hash: Hash;
_dataHash: Hash;
_sequence: Sequence;
}>;
/**
* Zod schema for payload with storage metadata
*/
const PayloadWithStorageMetaZod: ZodType<PayloadWithStorageMeta>;
/**
* Sequence validation schemas
*/
const LocalSequenceToStringZod: ZodType<string>;
const LocalSequenceFromStringZod: ZodType<LocalSequence>;
const QualifiedSequenceToStringZod: ZodType<string>;
const QualifiedSequenceFromStringZod: ZodType<QualifiedSequence>;
const SequenceToStringZod: ZodType<string>;
const SequenceFromStringZod: ZodType<Sequence>;
/**
* Helper to add storage metadata validation to existing Zod schema
*/
function WithStorageMetaZod<T extends ZodType<any>>(
valueZod: T
): ZodType<StorageMeta & T>;Usage Examples:
import {
StorageMetaZod,
PayloadWithStorageMetaZod,
SequenceFromStringZod,
WithStorageMetaZod
} from "@xyo-network/payload-model";
import * as z from "zod";
// Validate storage metadata
const storageData = {
_hash: "0x123...",
_dataHash: "0x456...",
_sequence: "1234567890abcdef12345678"
};
const validatedStorage = StorageMetaZod.parse(storageData);
console.log("Valid storage metadata:", validatedStorage);
// Validate payload with storage metadata
const payloadData = {
schema: "network.example.test",
data: "test data",
_hash: "0x123...",
_dataHash: "0x456...",
_sequence: "1234567890abcdef12345678"
};
const validatedPayload = PayloadWithStorageMetaZod.parse(payloadData);
// Create custom schema with storage metadata
const CustomPayloadZod = z.object({
schema: z.literal("network.example.custom"),
message: z.string(),
timestamp: z.number()
});
const CustomPayloadWithStorageZod = WithStorageMetaZod(CustomPayloadZod);
// Validate sequence
const sequenceString = "1234567890abcdef12345678";
const validatedSequence = SequenceFromStringZod.parse(sequenceString);
console.log("Valid sequence:", validatedSequence);StorageMeta: Complete storage metadata interfaceDataHashStorageMeta: Data hash metadata interfaceHashStorageMeta: Complete hash metadata interfaceSequenceStorageMeta: Sequence metadata interfaceSequence: Union of LocalSequence and QualifiedSequenceLocalSequence: Epoch + Nonce sequence typeQualifiedSequence: LocalSequence + Address sequence typeEpoch: Timestamp component of sequenceNonce: Hash + index component of sequenceWithStorageMeta<T>: Add complete storage metadata to typeWithHashStorageMeta<T>: Add hash metadata to typeWithSequenceStorageMeta<T>: Add sequence metadata to typeSequenceConstants: Sequence component lengths and limitsLocalSequenceConstants: Local sequence specific constantsQualifiedSequenceConstants: Qualified sequence specific constantsSequenceParser: Sequence parsing and manipulation utility classSequenceComparer.local: Compare sequences by local componentSequenceComparer.qualified: Compare sequences by full qualified sequenceInstall with Tessl CLI
npx tessl i tessl/npm-xyo-network--payload-model