| ← Back to Main Documentation | Core Systems Index |
Producer Delegation & Range-Based Quantity Control
Last Updated: Mon 16 Jul 2025 - Updated for wallet-first architecture and latest path specifications
Overview
This document specifies how Plings implements range-based quantity control for producer delegation, enabling manufacturers like Coca-Cola to delegate production to factories while maintaining strict offline control over production quantities.
Key Update: Now uses wallet-first architecture with paths like 2.3j.4.5Q.3L8z (class pointer separate) and HD derivations m/44'/501'/1'/3'/1255'/2'/5847'/90000'.
Core Requirements
- Offline-first: Factories must be able to produce millions of items without API calls
- No pre-registration: Items are only registered when first scanned/used
- Exact quantity control: Manufacturers must be able to limit production to exact quantities
- Cryptographic security: Impossible to forge identifiers outside authorized ranges
- Range enforcement: Built into path structure, not dependent on real-time verification
Architecture Overview
Range-Embedded Path Allocation
Instead of tracking usage counters in real-time, Plings embeds quantity limits directly into the path allocation structure:
Manufacturer Allocation (Wallet-First):
├── Path Prefix: "2.3j.4.5Q" (Coca-Cola → Plant 1255 → Classic Coke → Batch 5847) + Class Pointer
├── Authorized Range: instances 1-90,000
├── HD Derivation: m/44'/501'/1'/3'/1255'/2'/5847'/[1:90000] (Wallet v1)
└── Delegation Key: Private key for this specific batch+range
Key Changes:
- Wallet-first:
m/44'/501'/1'/...(wallet version 1) - Plant delegation:
1255represents specific factory/plant ID - Class pointer:
4K7mX9abDcEseparate 11-character pointer for Classic Coke - Solana standard: Uses
501'coin type for Solana blockchain compatibility
Factory Production System
class FactoryProduction {
constructor(allocation) {
// Hard-coded from manufacturer allocation
this.batchPath = allocation.path_prefix; // "2.3j.4.5Q" (class pointer separate)
this.authorizedRange = allocation.range; // { start: 1, end: 90000 }
this.currentInstance = allocation.range.start; // 1
this.privateKey = allocation.delegation_key; // Factory's private key
this.walletVersion = allocation.wallet_version; // 1 (for wallet v1)
}
produceNextItem() {
// Built-in range enforcement
if (this.currentInstance > this.authorizedRange.end) {
throw new Error(`Production halted: Exceeded authorized range (${this.authorizedRange.end})`);
}
// Generate path and cryptographic key offline
const path = `${this.batchPath}.${this.currentInstance}`;
const hdDerivation = this._pathToHDDerivation(path);
const instanceKey = deriveHDKey(this.privateKey, hdDerivation);
this.currentInstance++;
return {
path: path, // "2.3j.4.5Q.2aB" (class pointer separate)
instanceKey: instanceKey, // Base58 encoded public key
hdDerivation: hdDerivation, // "m/44'/501'/1'/3'/1255'/2'/5847'/42750'"
qrCodeData: instanceKey // What goes on the physical tag
};
}
_pathToHDDerivation(path) {
// Convert path to wallet-first HD derivation
// "2.3j.4.5Q.2aB" → "m/44'/501'/1'/3'/1255'/2'/5847'/42750'"
const parts = path.split('.');
let derivation = `m/44'/501'/${this.walletVersion}'`;
for (const part of parts) {
// All path segments are regular indices (class information via separate pointer)
derivation += `/${part}'`;
}
return derivation;
}
}
Range Allocation Registry
The Plings registry maintains authorized ranges for offline verification:
// Cached locally for offline verification
const rangeRegistry = {
"2.3j.4.5Q": {
manufacturer: "Coca-Cola",
plant_id: 1255,
plant_name: "Atlanta",
product_class: "Classic Coke",
class_pointer: "4K7mX9abDcE",
authorized_range: { start: 1, end: 90000 },
delegation_date: "2025-07-15",
status: "active",
wallet_version: 1,
delegation_key_hash: "abc123...", // For verification
},
"2.3k.4.5R": {
manufacturer: "Coca-Cola",
plant_id: 1256,
plant_name: "Mexico City",
product_class: "Classic Coke",
class_pointer: "4K7mX9abDcE",
authorized_range: { start: 1, end: 90000 },
delegation_date: "2025-07-16",
status: "active",
wallet_version: 1
}
};
Verification Process
Range Compliance Verification
function verifyInstanceInAuthorizedRange(path, instanceKey) {
// Parse path: "2.3j.4.5Q.2aB" (class pointer separate)
const pathParts = path.split('.');
const batchPath = pathParts.slice(0, 4).join('.'); // "2.3j.4.5Q"
const instanceNumber = parseInt(pathParts[4]); // 42750
// Get allocation info from cached registry
const allocation = rangeRegistry[batchPath];
if (!allocation) {
return {
valid: false,
reason: "Batch not allocated",
error_code: "BATCH_NOT_ALLOCATED"
};
}
if (allocation.status !== 'active') {
return {
valid: false,
reason: `Batch status: ${allocation.status}`,
error_code: "BATCH_REVOKED"
};
}
// Verify instance is within authorized range
const { start, end } = allocation.authorized_range;
if (instanceNumber < start || instanceNumber > end) {
return {
valid: false,
reason: `Instance ${instanceNumber} outside authorized range ${start}-${end}`,
error_code: "RANGE_VIOLATION",
authorized_range: { start, end },
violation_amount: instanceNumber > end ? instanceNumber - end : start - instanceNumber
};
}
// Proceed to cryptographic verification with wallet-aware derivation
return verifyCryptographicDerivation(path, instanceKey, allocation.wallet_version);
}
Complete Verification Chain
function verifyPlingsIdentifier(path, instanceKey) {
// 1. Parse and validate path format
const pathValidation = validatePathFormat(path);
if (!pathValidation.valid) return pathValidation;
// 2. Verify instance is within authorized production range
const rangeValidation = verifyInstanceInAuthorizedRange(path, instanceKey);
if (!rangeValidation.valid) return rangeValidation;
// 3. Verify cryptographic derivation from delegation key
const cryptoValidation = verifyCryptographicDerivation(path, instanceKey);
if (!cryptoValidation.valid) return cryptoValidation;
// 4. All checks passed
return {
valid: true,
manufacturer: rangeValidation.manufacturer,
product_class: rangeValidation.product_class,
batch_info: extractBatchInfo(path),
verification_method: "range_controlled_delegation"
};
}
Delegation Management
Creating New Delegations
async function createProducerDelegation(manufacturerId, plantId, productClass, quantity, walletVersion = 1) {
// 1. Generate unique batch ID
const batchId = await getNextBatchId(manufacturerId, plantId, productClass);
// 2. Create path prefix (class pointer generated separately)
const pathPrefix = `${manufacturerId}.${plantId}.${productClass}.${batchId}`;
const classPointer = generateClassPointer(manufacturerId, plantId, productClass);
// 3. Define authorized range
const authorizedRange = { start: 1, end: quantity };
// 4. Derive delegation key using wallet-first architecture
const hdDerivation = `m/44'/501'/${walletVersion}'/${manufacturerId}'/${plantId}'/${productClass}'/${batchId}'`;
const delegationKey = deriveHardenedKey(getWalletMasterKey(walletVersion), hdDerivation);
// 5. Register in path registry
await registerRangeAllocation({
wallet_version: walletVersion,
path_prefix: pathPrefix,
authorized_range: authorizedRange,
delegation_key: delegationKey.publicKey,
hd_derivation: hdDerivation,
manufacturer: getManufacturerName(manufacturerId),
plant_id: plantId,
product_class: productClass,
class_pointer: classPointer,
allocated_quantity: quantity,
status: "active"
});
return {
wallet_version: walletVersion,
path_prefix: pathPrefix,
authorized_range: authorizedRange,
delegation_key: delegationKey.privateKey, // Sent securely to factory
public_key: delegationKey.publicKey // Stored in registry
};
}
Revoking Delegations
async function revokeDelegation(pathPrefix, reason) {
// 1. Update registry status
await updateRangeAllocation(pathPrefix, {
status: "revoked",
revoked_at: new Date().toISOString(),
revocation_reason: reason
});
// 2. Propagate to verification nodes
await propagateRegistryUpdate(pathPrefix);
// 3. Log audit trail
await logDelegationRevocation(pathPrefix, reason);
return {
revoked: true,
path_prefix: pathPrefix,
reason: reason,
effective_immediately: true
};
}
Example Scenarios
Scenario 1: Coca-Cola Delegates Classic Coke Production to Atlanta
// Coca-Cola creates delegation for Atlanta
const atlantaDelegation = await createProducerDelegation(
3, // Coca-Cola manufacturer ID
1255, // Atlanta plant ID
2, // Classic Coke product class
90000 // 90,000 cans authorized
);
// Result:
// Path: "2.3j.4.5Q"
// Range: 1-90,000
// HD Derivation: m/44'/501'/1'/3'/1255'/2'/5847'/[1:90000]
// Atlanta can produce: 2.3j.4.5Q.2 through 2.3j.4.5Q.3L8z
// Atlanta production system configured with:
const atlantaProduction = new FactoryProduction({
path_prefix: "2.3j.4.5Q",
range: { start: 1, end: 90000 },
delegation_key: atlantaDelegation.delegation_key,
wallet_version: 1
});
Scenario 2: Atlanta Attempts Overproduction
// Atlanta produces authorized quantity
for (let i = 1; i <= 90000; i++) {
const can = atlantaProduction.produceNextItem();
// Success: generates 2.3j.4.5Q.2, 2.3j.4.5Q.3, ..., 2.3j.4.5Q.3L8z
}
// Atlanta attempts to produce beyond authorization
try {
const extraCan = atlantaProduction.produceNextItem(); // Would be 2.3j.4.5Q.3L9A
} catch (error) {
console.log(error.message);
// "Production halted: Exceeded authorized range (90000)"
}
// If Atlanta manually tries to create unauthorized instance:
const unauthorizedPath = "2.3j.4.5Q.3L92"; // Class pointer separate
const fakeKey = deriveHDKey(atlantaDelegation.delegation_key, "m/44'/501'/1'/3'/1255'/2'/5847'/90001'");
// Verification will fail:
const verification = verifyPlingsIdentifier(unauthorizedPath, fakeKey);
// Result: { valid: false, reason: "Instance 90001 outside authorized range 1-90000" }
Scenario 3: Transferring Production to Mexico
// Coca-Cola revokes Atlanta's future production
await revokeDelegation("2.3j.4.5Q", "Production transferred to Mexico plant");
// Coca-Cola creates new delegation for Mexico
const mexicoDelegation = await createProducerDelegation(
3, // Coca-Cola
1256, // Mexico plant ID
2, // Classic Coke
90000 // 90,000 cans authorized
);
// Result: Mexico gets path "2.3k.4.5R" with range 1-90,000 (class pointer separate)
// Atlanta's old delegation for "2.3j.4.5Q" is revoked
// No production overlap or confusion possible
Database Schema
Range Allocation Table
CREATE TABLE range_allocations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
wallet_version INTEGER NOT NULL,
path_prefix VARCHAR(50) NOT NULL,
manufacturer_id INTEGER NOT NULL,
plant_id INTEGER NOT NULL,
product_class INTEGER NOT NULL,
class_pointer VARCHAR(11) NOT NULL,
batch_id INTEGER NOT NULL,
authorized_start INTEGER NOT NULL,
authorized_end INTEGER NOT NULL,
delegation_public_key TEXT NOT NULL,
hd_derivation VARCHAR(100) NOT NULL,
status VARCHAR(20) DEFAULT 'active',
allocated_at TIMESTAMP DEFAULT NOW(),
revoked_at TIMESTAMP NULL,
revocation_reason TEXT NULL,
CONSTRAINT fk_wallet_version FOREIGN KEY (wallet_version)
REFERENCES wallet_versions(version_id),
CONSTRAINT fk_manufacturer FOREIGN KEY (wallet_version, manufacturer_id)
REFERENCES manufacturer_registry(wallet_version, manufacturer_index),
CONSTRAINT unique_path_per_wallet UNIQUE (wallet_version, path_prefix),
CONSTRAINT valid_range CHECK (authorized_start <= authorized_end),
CONSTRAINT valid_status CHECK (status IN ('active', 'revoked', 'completed')),
CONSTRAINT valid_class_pointer CHECK (length(class_pointer) = 11)
);
CREATE INDEX idx_range_allocations_wallet_path ON range_allocations(wallet_version, path_prefix);
CREATE INDEX idx_range_allocations_manufacturer ON range_allocations(wallet_version, manufacturer_id);
CREATE INDEX idx_range_allocations_status ON range_allocations(status);
CREATE INDEX idx_range_allocations_plant ON range_allocations(plant_id);
Security Considerations
Range Enforcement Security
- Built-in Limits: Range limits are embedded in factory systems, not dependent on network
- Cryptographic Proof: Each instance requires valid cryptographic derivation
- Registry Verification: Offline verification checks both range and cryptography
- Audit Trail: Complete history of all delegations and revocations
- Immutable Allocation: Once allocated, ranges cannot be retroactively changed
Attack Prevention
- Overproduction: Factory systems halt at exact range limits
- Range Extension: Impossible without new delegation from manufacturer
- Key Reuse: Each batch gets unique delegation key
- Replay Attacks: Instance numbers prevent duplicate generation
- Registry Poisoning: Cryptographic verification prevents fake entries
Implementation Guidelines
For Client Applications
// Cache range registry for offline verification
const cacheRangeRegistry = async () => {
const registry = await fetchRangeRegistry();
localStorage.setItem('plings_range_registry', JSON.stringify(registry));
localStorage.setItem('plings_registry_updated', Date.now().toString());
};
// Verify using cached registry (works offline)
const verifyOffline = (path, instanceKey) => {
const cachedRegistry = JSON.parse(localStorage.getItem('plings_range_registry') || '{}');
return verifyInstanceInAuthorizedRange(path, instanceKey, cachedRegistry);
};
For Factory Systems
// Initialize production system with delegation
const initializeProduction = (delegation) => {
// Validate delegation format
if (!delegation.path_prefix || !delegation.authorized_range || !delegation.delegation_key) {
throw new Error('Invalid delegation format');
}
// Create production instance with hard limits
return new FactoryProduction(delegation);
};
// Secure key storage
const storeDelegationKey = (key) => {
// Use HSM or secure enclave for production
// Never log or expose private keys
return secureKeyStorage.store(key);
};
Future Enhancements
Planned Features
- Multi-line Allocation: Split single batch across multiple production lines
- Dynamic Range Adjustment: Modify ranges without creating new batches
- Predictive Allocation: AI-driven quantity forecasting
- Real-time Monitoring: Optional production telemetry without blocking offline operation
- Cross-plant Coordination: Shared batch allocation between multiple factories
Scalability Considerations
- Registry Size: Efficient indexing for millions of range allocations
- Verification Speed: Sub-millisecond offline verification with cached registry
- Key Derivation: Hardware acceleration for cryptographic operations
- Distribution: CDN-based registry distribution for global offline access
This specification ensures that producer delegation provides manufacturers with precise quantity control while maintaining Plings’ core offline-first architecture and cryptographic security guarantees.