MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

I Built a Feature in 1 Hour, Not a Day

2025-12-20 00:47:01

🧠 Introduction

A year ago, this feature would’ve stolen my entire workday.

You know the kind 👇

Requirements look simple

UI seems “straightforward”

Backend is “just CRUD”

And yet…

☕ Coffee goes cold
😵‍💫 Brain melts
💥 Git commits turn emotional

Last week, I built the same type of feature in one focused hour.

Same codebase.
Same language.
Same developer (me).

The difference wasn’t speed typing.
It was how I thought about the feature before touching the keyboard.

🧩 The Feature That Used to Drain My Day

Nothing fancy. Just classic enterprise app stuff:

Form-based UI

Validation

API integration

Save + edit flow

Conditional rendering

Earlier, my workflow looked like this:

Start coding UI

Realize backend needs tweaking

Modify API

Break another screen

Add custom validation

Duplicate logic “just this once”

Fix edge cases at the end (panic phase)

❌ That’s not development.
✅ That’s damage control.

🔄 What Changed This Time
♻️ Reusable Thinking > Custom Thinking

The biggest shift came from one question:

“Have I already solved 80% of this problem somewhere else?”

Turns out — I had.

Similar forms

Similar validations

Same API response shape

I wasn’t missing code.
I was missing reuse discipline.

⚙️ Automating the Boring Middle

I stopped hand-wiring things I could standardize:

Form state

Validation rules

API error mapping

Once these become predictable,
features stop being scary.

⏳ The 1-Hour Build (Step by Step)
🧠 Step 1: Define Inputs & Outputs (10 minutes)

Before coding, I answered:

What data goes in?

What shape comes out?

What can fail?

I wrote this in plain English first.

No IDE.
No distractions.
Just clarity.

♻️ Step 2: Reuse Before You Write (15 minutes)

I reused:

An existing form component

A shared validation schema

A common API wrapper

No pride.
No “I’ll clean it later”.

🧱 Step 3: Thin Backend, Smart Frontend (20 minutes)

Instead of creating custom endpoints, I used:

A generic POST handler

Config-driven behavior

🧠 Less backend code = fewer surprises.

🧪 Code Example (Simplified)

Here’s the pattern that saved me time — config-driven forms.

// formConfig.ts
export const userFormConfig = {
  fields: [
    { name: "email", type: "email", required: true },
    { name: "role", type: "select", options: ["admin", "user"] }
  ],
  endpoint: "/api/users"
};
// ReusableForm.tsx
function ReusableForm({ config }) {
  const { fields, endpoint } = config;

  return (
    <form onSubmit={(data) => api.post(endpoint, data)}>
      {fields.map(field => (
        <Input key={field.name} {...field} />
      ))}
    </form>
  );
}

✨ This isn’t fancy.
🔁 It’s repeatable — and repeatability is speed.

🧠 Best Practices I Learned the Hard Way

Design patterns, not features

Write code assuming you’ll reuse it next week

If it feels repetitive → it deserves abstraction

Time spent thinking upfront saves hours later

“Simple” features expose bad architecture fast

⚠️ Common Pitfalls (I’ve Fallen Into All of These)

Over-customizing too early

Ignoring existing utilities

Mixing business logic into UI

Coding for today, not the next 5 features

Refactoring after shipping instead of before starting

💬 Community Corner

I’m curious 👇

What feature surprised you by being much faster than expected?

What abstraction saved you the most time?

Do you prefer config-driven reuse or explicit code?

Drop your stories, patterns, or counter-arguments in the comments.
Different teams solve this differently — and that’s the fun part.

❓ FAQ

  1. Was this because of AI tools?
    No. This was about architecture and reuse — not autocomplete.

  2. Is this approach good for startups?
    Especially for startups. Speed + consistency matters most there.

  3. Doesn’t abstraction slow you down initially?
    Yes. Once. Then it pays you back repeatedly.

  4. What if requirements change?
    Config-driven designs adapt faster than hardcoded flows.

  5. Is this more frontend or backend focused?
    Both — but frontend benefits immediately.

  6. Can juniors apply this?
    Absolutely. Start small: reuse one component at a time.

  7. What’s the biggest takeaway?
    👉 Think in systems, not tasks.

🎯 Conclusion

That 1-hour feature wasn’t luck.

It was the result of:

Fewer decisions

Better reuse

Respecting my future self’s time

If every feature feels heavier than it should,
don’t work faster — work differently.

If this resonated, give it a ❤️, share it with your team,
or follow me for more real-world dev lessons —
no fluff, just scars and solutions.

🔗 References

React Docs – Reusability Patterns: https://react.dev

Martin Fowler on Refactoring: https://martinfowler.com

Clean Architecture Overview: https://8thlight.com/insights/clean-architecture

Entity Framework Core Raw SQL — From FromSql() to Production‑Grade Safety

2025-12-20 00:42:57

Entity Framework Core Raw SQL — From FromSql() to Production‑Grade Safety

Entity Framework Core Raw SQL — From FromSql() to Production‑Grade Safety

Most .NET developers eventually hit the same moment with Entity Framework Core:

“LINQ is great… but I need raw SQL here.”

That’s when APIs like FromSqlRaw, ExecuteSqlRaw, and FromSqlInterpolated enter the picture — and that’s also where security, performance, and correctness can silently go wrong.

This article goes deeper than the docs:

  • Why EF Core deprecated some APIs
  • What really happens inside EF Core, the JIT, and the database engine
  • How to use raw SQL safely without losing performance
  • Mental models used by senior .NET engineers in production systems

If you’ve ever wondered “what’s the real difference?”, this post is for you.

Table of Contents

  1. The Mental Model: Why Raw SQL Exists in EF Core
  2. FromSql vs FromSqlRaw vs FromSqlInterpolated
  3. Deprecated APIs — What Changed and Why
  4. What Happens Under the Hood (EF Core + ADO.NET + SQL Server)
  5. Security Deep Dive: SQL Injection at the Instruction Level
  6. Performance Reality: Query Plans, Parameterization, and Caching
  7. ExecuteSqlRaw for Commands (UPDATE / DELETE)
  8. Advanced Patterns Used in Production
  9. Common Pitfalls (and How Senior Devs Avoid Them)
  10. Production Checklist

1. Mental Model: Why Raw SQL Exists in EF Core

EF Core was designed around LINQ-to-Entities, but no ORM can fully replace SQL.

Raw SQL exists for three main reasons:

  1. Expressiveness

    Some queries (CTEs, window functions, hints) are awkward or impossible in LINQ.

  2. Performance

    Hand‑tuned SQL can outperform generated queries in hot paths.

  3. Integration

    Legacy databases, views, stored procedures, and reporting queries.

Key idea:

EF Core does not bypass ADO.NET.

Raw SQL still flows through parameterization, command preparation, and execution plans.

2. FromSql vs FromSqlRaw vs FromSqlInterpolated

FromSql() (Deprecated)

Historically:

context.Users.FromSql("SELECT * FROM Users WHERE Name = {0}", name);
  • Automatically parameterized
  • Safer by default
  • Removed to reduce ambiguity and API surface

FromSqlRaw()

context.Users
    .FromSqlRaw("SELECT * FROM Users WHERE Name = @name",
        new SqlParameter("@name", name));

Characteristics:

  • Maximum control
  • Zero magic
  • You are responsible for parameter safety

FromSqlInterpolated() (Recommended)

context.Users
    .FromSqlInterpolated($"SELECT * FROM Users WHERE Name = {name}");

EF Core converts interpolation into parameters automatically.

3. Deprecated APIs — What Changed and Why

EF Core removed:

  • FromSql
  • ExecuteSql
  • SqlQuery

Reason:

  • Too easy to introduce SQL injection
  • Ambiguous safety guarantees
  • Harder to audit at scale

4. What Happens Under the Hood

Pipeline:

  1. EF Core builds a relational command
  2. Parameters become DbParameter
  3. ADO.NET executes the command
  4. Database parses, optimizes, executes
  5. Results stream back

Parameterized SQL enables plan reuse.

5. SQL Injection — Real Mechanics

Injection changes the SQL parse tree.

Bad:

FromSqlRaw($"SELECT * FROM Users WHERE Name = '{input}'");

Good:

FromSqlInterpolated($"SELECT * FROM Users WHERE Name = {input}");

6. Performance Reality

  • Parameterized SQL = cached plans
  • String SQL = recompilation
  • Compilation cost adds latency

Secure SQL is almost always faster SQL.

7. ExecuteSqlRaw for Commands

context.Database.ExecuteSqlRaw(
    "UPDATE Users SET IsActive = 0 WHERE LastLogin < @date",
    new SqlParameter("@date", cutoff));

8. Advanced Production Patterns

Hybrid LINQ + SQL

var query =
    context.Users
        .FromSqlInterpolated($"SELECT * FROM Users WHERE IsActive = {true}")
        .AsNoTracking()
        .Where(u => u.Role == "Admin");

9. Common Pitfalls

  • Concatenating user input
  • Forgetting AsNoTracking()
  • Assuming raw SQL bypasses EF Core
  • Ignoring execution plans

10. Production Checklist

  • [ ] Parameterized queries only
  • [ ] No string concatenation
  • [ ] Execution plans reviewed
  • [ ] Load tested hot paths
  • [ ] Logging enabled

Final Thought

Raw SQL is not an escape hatch.

It’s a precision tool — powerful, fast, and dangerous if misunderstood.

Use it like a scientist, not like a cowboy.

# `@xchainjs/xchain-ethereum`

2025-12-20 00:42:23

@xchainjs/xchain-ethereum is the official Ethereum client for the XChainJS ecosystem — a modular, TypeScript-first SDK for building cross-chain wallets, crypto applications, and DeFi tooling using a unified API.

This package provides:

  • an Ethereum (EVM) client implementation
  • address generation and validation
  • balance and transaction history lookup
  • transaction creation, signing, and broadcasting
  • gas and fee estimation helpers

Source package: https://github.com/xchainjs/xchainjs-lib/tree/master/packages/xchain-ethereum

Official docs: https://docs.xchainjs.org/xchain-client/xchain-ethereum/

Features

  • ✅ TypeScript-first Ethereum SDK
  • ✅ EVM-compatible chain support
  • ✅ Address derivation from mnemonic
  • ✅ Address validation
  • ✅ Balance and transaction history
  • ✅ ETH and ERC-20 transfers
  • ✅ Gas price and fee estimation
  • ✅ Unified API aligned with other XChainJS clients

How It Works

  • Built on top of ethers.js for Ethereum RPC interaction
  • Uses shared XChainJS abstractions and types
  • Designed to behave consistently with other chain clients (BTC, LTC, THORChain, etc.)

Core dependencies:

  • ethers
  • @xchainjs/xchain-client
  • @xchainjs/xchain-util

Docs:

Installation

Install the package

npm install @xchainjs/xchain-ethereum

Peer dependencies

npm install @xchainjs/xchain-client @xchainjs/xchain-util ethers

Basic Usage Examples

Create an Ethereum Client

import { Client } from '@xchainjs/xchain-ethereum'
import { Network } from '@xchainjs/xchain-client'

const phrase = 'your mnemonic phrase here'

const ethClient = new Client({
  phrase,
  network: Network.Mainnet,
})

Get Address and Validate It

const address = ethClient.getAddress()
console.log('Address:', address)

const isValid = ethClient.validateAddress(address)
console.log('Valid:', isValid)

Get Balance

const balances = await ethClient.getBalance(address)
console.log(balances)

Balances are returned in base units and can be converted using utilities from
@xchainjs/xchain-util.

Transfer ETH

import { assetAmount, assetToBase } from '@xchainjs/xchain-util'

const recipient = '0xRecipientAddressHere'
const amount = assetToBase(assetAmount(0.01))

const txHash = await ethClient.transfer({
  recipient,
  amount,
  memo: 'ETH transfer',
})

console.log('TX hash:', txHash)
console.log('Explorer:', ethClient.getExplorerTxUrl(txHash))

Transfer ERC-20 Tokens

const tokenAddress = '0xTokenContractAddress'
const txHash = await ethClient.transfer({
  recipient,
  amount,
  asset: {
    chain: 'ETH',
    symbol: `USDT-${tokenAddress}`,
    ticker: 'USDT',
  },
})

Get Transaction Data

const txHash = '0xTransactionHash'
const txData = await ethClient.getTransactionData(txHash)
console.log(txData)

When to Use This Package

Use @xchainjs/xchain-ethereum if you are:

  • building a crypto wallet
  • interacting with Ethereum or EVM chains
  • handling ETH and ERC-20 transfers
  • building DeFi frontends or backends
  • using XChainJS for multi-chain applications

Useful Links

Summary

@xchainjs/xchain-ethereum provides a clean, consistent, and production-ready
Ethereum client for the XChainJS ecosystem.

It allows developers to interact with Ethereum using the same abstractions as
other blockchains, making it easier to build cross-chain applications.

2026’da Frontend Gelişiminin Yeni Yönü: Framework’lerin Ötesinde

2025-12-20 00:42:00

Frontend artık sadece React veya Vue değil; 2026’da trend, server-first mimariler, edge rendering ve AI destekli geliştirme deneyimi.

Framework savaşlarının sonu mu geliyor?

Bir dönem her geliştirici topluluğunda aynı tartışma dönerdi: React mi, Vue mu, Angular mı?
Bugünse bu savaşlar yerini daha olgun bir anlayışa bıraktı. Artık mesele “hangi framework” değil, nasıl bir mimariyle geliştirdiğin.

2026’ya gelindiğinde frontend ekosistemi yalnızca component tabanlı yapılardan ibaret değil. Artık gündemde server-first yaklaşımlar, edge rendering, AI destekli geliştirme ve developer experience (DX) odaklı yapılar var.
Yani mesele framework değil, felsefe.

Server-first yaklaşımı – Tarayıcıdan önce sunucu

Yeni nesil framework’ler artık “her şeyi tarayıcıda çalıştırmak” yerine, işi mümkün olduğunca sunucu tarafına taşıyor.
Next.js, SvelteKit ve Remix bu dönüşümün öncülerinden.

Server-first yaklaşımının avantajları:

  • İlk yükleme süresi ciddi oranda kısalır.
  • SEO performansı yükselir.
  • Kullanıcı boş sayfa beklemeden içerik görür.

React 19’un sunduğu Server Components özelliği bu anlayışın en somut örneği. Artık bazı bileşenler tamamen sunucuda render edilebiliyor, istemciye sadece işlenmiş HTML gönderiliyor.

Bu kod istemcide çalışmaz; yalnızca sonuç çıktısı gelir.
Sonuç: Daha az JS, daha yüksek hız.

Edge rendering – Kullanıcıya en yakın noktada render

“Server-side rendering” artık yeterli değil. 2026’da önemli olan, nerede render ettiğin.
Edge rendering, içeriği kullanıcıya en yakın fiziksel konumda oluşturmayı hedefliyor.

Vercel Edge Functions, Cloudflare Workers ve Deno Deploy gibi servisler, kodu global CDN katmanında çalıştırıyor.
Yani İstanbul’daki bir kullanıcı isteği Frankfurt’ta, Tokyo’daki biri içinse Singapur’da render ediliyor.

Bu sayede:

  • Sayfa yüklenme süresi küresel ölçekte dengelenir.
  • API gecikmesi azalır.
  • Kullanıcı deneyimi bölgesel farklardan etkilenmez.

Edge rendering artık performans optimizasyonu değil, altyapı stratejisi haline geldi.

AI destekli geliştirme – Kod yazmak değil, yönlendirmek

Yapay zekâ araçları 2026 itibarıyla frontend dünyasının ayrılmaz bir parçası haline geldi.
G*itHub Copilot, Cursor, bolt.new ve v0.dev* gibi platformlar yalnızca kod tamamlama değil, bileşen üretimi, test senaryosu ve dokümantasyon oluşturma gibi görevleri de üstleniyor.

Bu dönüşümün sonucu olarak geliştiricinin rolü değişiyor:
Artık odak nasıl kod yazılır değil, AI’ye neyi nasıl tarif ederiz.

Yeni beceri seti: Prompting
Doğru tanımlanmış bir istem (prompt), bir bileşeni sıfırdan manuel yazmaktan çok daha hızlı sonuç veriyor.
Bu da zamanla “AI-assisted developer” kavramını doğurdu — yani yapay zekâyı kod ortağı olarak kullanan geliştirici.

Developer Experience (DX) – Geliştirici deneyimi kazanıyor

Framework seçiminde eskiden performans, benchmark skorları veya syntax ön plandaydı.
Artık belirleyici olan şey developer experience (DX).

DX’i güçlü kılan faktörler:

  • Açıklayıcı hata mesajları
  • Dosya tabanlı yönlendirme
  • Hızlı hot reload
  • Az konfigürasyonla çalışan CLI’lar
  • Tutarlı dokümantasyon

Örneğin:

  • Next.js: “zero-config” proje başlatma kolaylığı.
  • Remix: anlamlı hata mesajları ve yönlendirmeler.
  • SvelteKit: dosya bazlı routing ile karmaşık yapıların sadeleştirilmesi.

DX artık sadece geliştirme süresini değil, ekip moralini de belirliyor.
Kısacası iyi DX = daha az stres + daha fazla üretkenlik.

Islands architecture – Gerektiğinde canlanan bileşenler

Yeni nesil projeler “her şeyi hydrate etme” dönemini kapatıyor.
Islands architecture adı verilen yaklaşımda, yalnızca etkileşimli alanlar tarayıcıda canlandırılıyor.

Astro ve Qwik bu modelin önde gelen temsilcileri.
Bu sayede:

  • Sayfa 10 kata kadar daha hızlı yüklenir.
  • Gereksiz JavaScript çalışmaz.
  • Enerji tüketimi azalır, tarayıcı yükü hafifler.

Kısacası sayfa artık tamamen “dinamik” değil, yalnızca gerektiğinde “canlı”.
Modern web artık hem hızlı hem çevreci olmayı hedefliyor.

Framework değil, felsefe seçimi

Tüm bu gelişmeler gösteriyor ki artık “React mi Vue mu?” sorusu tek başına anlamını yitirdi.
Geliştiricinin odağı “hangi araç”tan “hangi yaklaşım”a kaydı.

Yeni dönemde başarı, doğru framework’ü değil;
doğru mimariyi, doğru ortamda, doğru araçlarla kullanabilmekte yatıyor.

  • Server-first: hız ve SEO için
  • Edge rendering: küresel erişim için
  • AI-assisted development: verimlilik için
  • DX odaklı framework’ler: sürdürülebilirlik için
  • Islands architecture: enerji ve performans dengesi için

Bu yaklaşımlar artık modern frontend’in temel yapı taşları.
Framework’ler bu yapıların yalnızca araçları haline geldi.

Frontend geliştiricisinin yeni rolü

Bugünün frontend geliştiricisi sadece arayüz kodlayan biri değil.
Artık o:

  • Render stratejisini belirleyen,
  • Edge altyapısını yöneten,
  • AI araçlarını verimli kullanan,
  • Hem DX’i hem UX’i optimize eden kişi.

Bu çok boyutlu rol, frontend’i yazılım mimarisinin merkezine taşıyor.
Geliştirici artık “tasarım ile backend arasında köprü” değil, tüm deneyimin mimarı.

Sonuç : Framework’lerin ötesine geçmek

Framework’ler hâlâ önemini koruyor, ancak artık oyunun tek kuralı değiller.
2026 ve sonrasında kazanan, en popüler framework’ü kullanan değil,
doğru mimari yaklaşımı seçip onu en verimli şekilde uygulayabilen geliştirici olacak.

Server-first mimariler, edge rendering, AI destekli geliştirme ve DX odaklı yapılar,
önümüzdeki yıllarda frontend ekosisteminin yönünü tamamen değiştirecek.

Gerçek yenilik, framework’te değil; onunla ne kadar bilinçli çalıştığında gizli.

Guardium- Password Protector (Day-2)

2025-12-20 00:41:38

Manifest.json (chrome extension)

The manifest.json file is the backbone of a Chrome extension, acting as the primary metadata and configuration file that Chrome reads before loading or running the extension. It defines the extension’s identity—including its name, version, description, author, and icons—and clearly specifies how the extension behaves inside the browser. Through the manifest, developers declare permissions that control what browser APIs and websites the extension can access, ensuring security and user transparency. It also links all major components of the extension such as background service workers, content scripts, popups, options pages, and web-accessible resources, allowing Chrome to know when and where each part should execute. In Manifest Version 3 (MV3), manifest.json plays an even more critical role by enforcing modern security practices like non-persistent background execution, stricter permission handling, and improved performance, making it essential for building safe, efficient, and maintainable Chrome extensions.

Manifest.json (chrome extension)

{
  "manifest_version": 3,
  "name": "Guardium",
  "short_name": "Guardium",
  "description": "A secure browser-based password manager with autofill support",
  "version": "1.0.0",

  "action": {
    "default_title": "Open Guardium",
    "default_popup": "index.html"
  },

  "icons": {
    "16": "assets/icons/icon16.png",
    "32": "assets/icons/icon32.png",
    "48": "assets/icons/icon48.png",
    "128": "assets/icons/icon128.png"
  },

  "background": {
    "service_worker": "background.js",
    "type": "module"
  },

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["contentScript.js"],
      "run_at": "document_end",
      "all_frames": true
    }
  ],

  "permissions": [
    "activeTab",
    "tabs",
    "storage",
    "scripting",
    "alarms",
    "notifications"
  ],

  "host_permissions": [
    "<all_urls>"
  ],

  "web_accessible_resources": [
    {
      "resources": [
        "assets/icons/*",
        "injected/*.js"
      ],
      "matches": ["<all_urls>"]
    }
  ],

  "options_page": "options.html",

  "commands": {
    "open-guardium": {
      "suggested_key": {
        "default": "Ctrl+Shift+G",
        "mac": "Command+Shift+G"
      },
      "description": "Open Guardium popup"
    }
  },

  "minimum_chrome_version": "114"
}

Explanation of every line(manifest.json):-

 "manifest_version": 3,

🔹 Manifest Version

Specifies Manifest V3, the latest Chrome extension standard.

Enforces:

Better security

Service workers instead of background pages

Stricter permission control

  "name": "Guardium",

🔹 Extension Name

The full name displayed:

In Chrome Extensions page

In Chrome Web Store

Under the toolbar icon

"short_name": "Guardium",

🔹 Short Name

Used where space is limited (e.g., toolbar labels).

Optional but recommended for UI consistency.

  "description": "A secure browser-based password manager with autofill support",

🔹 Description

Brief summary of the extension’s purpose.

Visible in the Chrome Web Store and Extensions page.


  "version": "1.0.0",

Version Number

Used by Chrome to manage updates.

Must follow semantic versioning format (major.minor.patch).
Toolbar Action (Popup UI)
"action": {

🔹 Defines behavior of the extension icon in the toolbar.

"default_title": "Open Guardium",

🔹 Tooltip text shown when the user hovers over the extension icon.


    "default_popup": "index.html"

🔹 HTML file opened when the extension icon is clicked.
👉 This is your password manager UI (often a React build output).

  },

🔹 End of action configuration.

🎨 Icons

"icons": {

🔹 Declares extension icons in different sizes.

  "16": "assets/icons/icon16.png",

🔹 Used in:

Toolbar

Context menus


    "32": "assets/icons/icon32.png",

🔹 Used on high-DPI displays and system UI.

"48": "assets/icons/icon48.png",

🔹 Used on the Chrome Extensions page.


    "128": "assets/icons/icon128.png"

🔹 Used in the Chrome Web Store listing.


  },

🔹 End of icons section.

⚙ Background Service Worker

"background": {

🔹 Defines background logic of the extension.


    "service_worker": "background.js",

🔹 JavaScript file that:

Handles events

Listens for messages

Manages alarms, auth, encryption, etc.

⚠️ Runs only when needed (not persistent).

 "type": "module"

🔹 Enables ES modules:

Allows import / export

Cleaner and scalable architecture

  },

🔹 End of background configuration.

🌐 Content Scripts

 "content_scripts": [

🔹 Declares scripts injected into web pages.

 {

🔹 One content-script rule block.


      "matches": ["<all_urls>"],

🔹 Injects script on all websites.

Required for password managers (login form detection).

  "js": ["contentScript.js"],

🔹 JavaScript file injected into matching pages.

 "run_at": "document_end",

🔹 Script runs after DOM is loaded.

Ensures forms and inputs exist.

  "all_frames": true

🔹 Script runs inside:

Main page

All iframes (important for embedded login forms)


    }
  ],


🔹 End of content script declaration.

🔐 Permissions

 "permissions": [

🔹 Declares Chrome APIs the extension can use.

  "activeTab",

🔹 Temporary access to the currently active tab.

   "tabs",

🔹 Allows reading tab metadata (URL, ID, title).

 "storage",

🔹 Enables chrome.storage for saving encrypted passwords.

 "scripting",

🔹 Allows dynamic script injection (MV3 requirement).

 "alarms",

🔹 Enables scheduled background tasks.

  "notifications"

🔹 Allows user notifications (e.g., password saved).

  ],

🔹 End of permissions list.

🌍 Host Permissions

"host_permissions": [

🔹 Specifies which websites the extension can access.

"<all_urls>"

🔹 Allows interaction with all websites.

Required for autofill extensions.

  ],

🔹 End of host permissions.

📦 Web Accessible Resources

"web_accessible_resources": [

🔹 Allows web pages or content scripts to access extension files.

{

🔹 Resource rule object.

  "resources": [
        "assets/icons/*",
        "injected/*.js"
      ],

🔹 Files that can be accessed externally.

    "matches": ["<all_urls>"]

🔹 Websites allowed to access these resources.

 }
  ],

🔹 End of web-accessible resources.

⚙ Options Page


  "options_page": "options.html",

🔹 Settings page for the extension.

Used for:

Preferences

Security settings

Sync options

⌨ Keyboard Commands

"commands": {

🔹 Defines keyboard shortcuts.

 "open-guardium": {

🔹 Unique command identifier.

"suggested_key": {

🔹 Platform-specific shortcuts.

 "default": "Ctrl+Shift+G",
        "mac": "Command+Shift+G"

🔹 Shortcut keys for Windows/Linux and macOS.

 },

🔹 End of key definition.

"description": "Open Guardium popup"

🔹 Description shown in Chrome shortcut settings.

   }
  },

🔹 End of commands section.

🔎 Chrome Version Requirement

 "minimum_chrome_version": "114"

🔹 Ensures compatibility with required MV3 APIs.


}

🔹 End of manifest file.

✅ Final Summary

This manifest.json:

Fully complies with Manifest V3

Supports password management + autofill

Is Chrome Web Store ready

Covers UI, background, content scripts, permissions, security

# `@xchainjs/xchain-litecoin`

2025-12-20 00:39:21

Custom Litecoin (LTC) client and utilities for XChainJS — a lightweight TypeScript SDK for building cross-chain wallets, crypto payment flows, and DeFi tooling with a common interface.

This package provides:

  • a Litecoin Client implementation (UTXO-style chain)
  • address generation & validation
  • balance, transaction history, and transaction data lookup
  • fee estimation helpers (fee rates, fees with memo, etc.)

Source package: https://github.com/xchainjs/xchainjs-lib/tree/master/packages/xchain-litecoin

XChainJS docs: https://docs.xchainjs.org/xchain-client/xchain-litecoin/

Features

  • ✅ TypeScript-first Litecoin SDK
  • ✅ BIP44/84 address derivation support (mainnet & testnet paths)
  • ✅ Create addresses from a phrase (mnemonic)
  • ✅ Validate addresses
  • ✅ Get balances, tx history, and tx data by hash
  • ✅ Transfer LTC
  • ✅ Fee estimation helpers (getFeeRates, getFeesWithMemo, etc.)

How it works (under the hood)

  • Uses bitcoinjs-lib for UTXO transaction building and signing.
  • Uses SoChain API v2 as the default public data provider endpoint.
  • Explorer URLs reference Blockstream.
  • Depends on shared XChainJS packages: @xchainjs/xchain-client, @xchainjs/xchain-crypto, @xchainjs/xchain-util.

References:

Installation

Install the package

yarn add @xchainjs/xchain-litecoin

Peer dependencies

According to the official docs, install these as well:

yarn add @xchainjs/xchain-client @xchainjs/xchain-crypto @xchainjs/xchain-util axios bitcoinjs-lib coininfo wif

Basic usage examples

Connect wallet to a new Litecoin Client

Create a client instance, derive an address, validate it, and fetch its balance.

import { Client } from '@xchainjs/xchain-litecoin'
import { Network } from '@xchainjs/xchain-client'
import { baseToAsset } from '@xchainjs/xchain-util'

const connectWallet = async () => {
  const phrase = 'your mnemonic phrase here'
  const ltcClient = new Client({ network: Network.Mainnet, phrase })

  const address = ltcClient.getAddress()
  console.log('Address:', address)

  const isValid = ltcClient.validateAddress(address)
  if (!isValid) throw new Error('Invalid address')

  const balances = await ltcClient.getBalance(address)
  const readable = baseToAsset(balances[0].amount).amount()
  console.log('Balance:', readable.toString())
}

connectWallet().catch(console.error)

Transfer Litecoin (LTC)

Build and broadcast a transaction using the client.

import { Client, LTC_DECIMAL } from '@xchainjs/xchain-litecoin'
import { assetToBase, assetAmount } from '@xchainjs/xchain-util'

const transferLitecoin = async () => {
  const phrase = 'your mnemonic phrase here'
  const recipient = 'ltc recipient address here'

  const ltcClient = new Client({ phrase })

  const amount = assetToBase(assetAmount(0.01, LTC_DECIMAL))

  const txid = await ltcClient.transfer({
    amount,
    recipient,
    memo: 'memo',
  })

  console.log('TX sent:', txid)
  console.log('Explorer:', ltcClient.getExplorerTxUrl(txid))
}

transferLitecoin().catch(console.error)

Get transfer fees and fee rate estimations

import { Client } from '@xchainjs/xchain-litecoin'
import { baseToAsset } from '@xchainjs/xchain-util'

const returnFees = async () => {
  const phrase = 'your mnemonic phrase here'
  const ltcClient = new Client({ phrase })

  const { fast, fastest, average } = await ltcClient.getFees()
  console.log('Fast:', baseToAsset(fast).amount().toString())
  console.log('Fastest:', baseToAsset(fastest).amount().toString())
  console.log('Average:', baseToAsset(average).amount().toString())

  const feeRates = await ltcClient.getFeeRates()
  console.log('FeeRates:', feeRates)
}

returnFees().catch(console.error)

You can pass feeRate into transfer parameters:

// feeRates.fastest is a number
await ltcClient.transfer({
  amount,
  recipient,
  memo: 'memo test',
  feeRate: feeRates.fastest,
})

Get transaction data & transaction history

import { Client } from '@xchainjs/xchain-litecoin'

const transactionData = async () => {
  const phrase = 'your mnemonic phrase here'
  const ltcClient = new Client({ phrase })

  const hash = 'your tx hash'
  const txData = await ltcClient.getTransactionData(hash)
  console.log('TxData:', txData)
}

transactionData().catch(console.error)

Useful links