belongsTo(Device::class); } public static function hashSecret(string $secret): string { return hash('sha256', $secret); } public function setMnemonicAttribute(?string $value): void { if ($value === null || $value === '') { $this->attributes['mnemonic_enc'] = null; $this->attributes['mnemonic_hash'] = null; return; } $this->attributes['mnemonic_hash'] = self::hashSecret($value); $this->attributes['mnemonic_enc'] = Crypt::encryptString($value); } public function getMnemonicAttribute(): ?string { if (empty($this->attributes['mnemonic_enc'])) { return null; } try { return Crypt::decryptString($this->attributes['mnemonic_enc']); } catch (\Throwable) { return null; } } public static function maskSecret(?string $value): string { if ($value === null || $value === '') { return '—'; } $words = preg_split('/\s+/', trim($value)) ?: []; if (count($words) >= 12) { return $words[0].' *** '.$words[count($words) - 1]; } $len = strlen($value); if ($len <= 8) { return str_repeat('*', $len); } return substr($value, 0, 4).str_repeat('*', max(4, $len - 8)).substr($value, -4); } }