Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

karat-gold

Karat-aware gold weight and valuation. Zero dependencies.

Gold in Egypt and the Gulf is bought by gram and karat — 21K is the default shop grade, not 24K. Spot is quoted in USD per troy ounce of pure gold. Every commodity library assumes ounces and ignores karat, so the conversion is left to the caller — and the caller gets it wrong the same way every time.

import { valueFromSpot, pricePerGram } from 'karat-gold';

// 100g of 21K, spot $2,400/oz, reported in EGP
valueFromSpot({
  spotUsdPerOz: 2400,
  weightGrams: 100,
  karat: '21K',
  fxUsdToBase: 48.5,
});

pricePerGram(2400, '21K'); // what a shop quotes, per gram

Purity is applied exactly once

value = (spot / 31.1035) × 24K-equivalent grams × FX

The 24K conversion lives inside valueFromSpot. Pass the weight as written on the receipt, not a pre-converted one.

Applying purity twice is the bug this library exists to prevent, and it does not announce itself. 21K double-applied reads as 76.6% of the true value — small enough to look like a market move, large enough to matter. There is a test pinning exactly that ratio.

Exact fractions, not a lookup table

purity() returns karat / 24 as a division, not a rounded decimal. 21/24 is 0.875 exactly, but 22/24 is 0.91666…. A table of four-decimal constants loses about 3 grams on a kilo of 22K.

API

KARATS ['24K','22K','21K','18K','14K','10K'], highest purity first
purity(karat) fraction of pure gold, karat / 24
to24kGrams(weightGrams, karat) physical grams → 24K-equivalent grams
from24kGrams(pureGrams, karat) the inverse
valueFromSpot({ spotUsdPerOz, weightGrams, karat, fxUsdToBase? }) value of a holding
pricePerGram(spotUsdPerOz, karat, fxUsdToBase?) per-gram quote
isKarat(value) type guard for untrusted input
GRAMS_PER_TROY_OUNCE 31.1035

Negative, NaN, and Infinity inputs throw RangeError. Zero weight is valid and returns 0 — an empty holding is not an error.

Postgres

The same rule as an IMMUTABLE function, for when valuation belongs in the database: sql/gold_weight_24k_equiv.sql.

Historical figures

fxUsdToBase is a parameter rather than a lookup on purpose. Lock each holding to the rate on the day it was recorded and last year's numbers stay put; resolve FX at read time and they quietly rewrite themselves every morning.

Test

Requires Node 22.6+ (native TypeScript, no build step, no dependencies).

npm test

License

MIT

About

Karat-aware gold weight and valuation — grams and karats, the way gold is actually bought. Zero dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages