npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@permissionless-technologies/upd-sdk

v0.2.4

Published

Universal Private Dollar SDK — Non-rebasing stablecoin backed by stETH with stabilizer collateral management

Readme

UPD SDK — Universal Private Dollar

Integrate UPD minting and burning into your protocol. Non-rebasing stablecoin backed by stETH.

npm install @permissionless-technologies/upd-sdk

Quick Start

import { createPublicClient, http, parseEther } from 'viem'
import { mainnet } from 'viem/chains'
import { createUPDClient, quoteMintUPD } from '@permissionless-technologies/upd-sdk'

// 1. Create a client
const publicClient = createPublicClient({ chain: mainnet, transport: http() })
const client = createUPDClient({ publicClient, chainId: 1 })

// 2. Read data (no wallet needed)
const balance = await client.getUPDBalance('0x...')
const supply = await client.getTotalSupply()
const { totalStEthCollateral, totalUPDSupply } = await client.getCollateralInfo()

// 3. Quote a mint (pure math, no blockchain call)
const expectedUPD = quoteMintUPD(parseEther('1'), 2000n * 10n**18n)
// → 2000000000000000000000n (2000 UPD for 1 ETH at $2000)

Minting UPD

Send ETH → receive UPD (pegged to $1). The StabilizerNFT contract handles collateral allocation automatically.

import { createWalletClient, custom, parseEther } from 'viem'
import { createUPDClient, createMockAttestation } from '@permissionless-technologies/upd-sdk'

const walletClient = createWalletClient({ chain: mainnet, transport: custom(window.ethereum) })
const client = createUPDClient({ publicClient, walletClient, chainId: 1 })

// Get a price attestation (see Oracle section below)
const attestation = await fetchPriceFromYourOracle() // your implementation

// Mint UPD
const txHash = await client.mint({
  to: userAddress,
  ethAmount: parseEther('1'),
  priceAttestation: attestation,
})

Burning UPD

Send UPD → receive stETH back.

import { parseUnits } from 'viem'

const txHash = await client.burn({
  updAmount: parseUnits('2000', 18),
  priceAttestation: attestation,
})

Quote Functions

Pure math — no blockchain calls needed. Use these to show users expected amounts before a transaction.

import { quoteMintUPD, quoteBurnUPD, collateralizationRatio } from '@permissionless-technologies/upd-sdk'

// How much UPD for 1 ETH at $2000?
quoteMintUPD(parseEther('1'), 2000n * 10n**18n) // → 2000 UPD

// How much stETH for 2000 UPD at $2000?
quoteBurnUPD(parseUnits('2000', 18), 2000n * 10n**18n) // → 1 stETH

// Calculate collateralization ratio
collateralizationRatio(parseEther('1.25'), 2000n * 10n**18n, parseUnits('2000', 18)) // → 12500 (125%)

Oracle Integration

Minting and burning require a signed price attestation from an authorized oracle signer. The attestation format:

interface PriceAttestationQuery {
  price: bigint          // ETH/USD price, 18 decimals (e.g. 2000e18)
  decimals: number       // Always 18
  dataTimestamp: bigint   // Milliseconds since epoch
  assetPair: `0x${string}` // keccak256("MORPHER:ETH_USD")
  signature: `0x${string}` // ECDSA sig from authorized signer
}

For testing/development, use the mock helper:

import { createMockAttestation } from '@permissionless-technologies/upd-sdk'

const attestation = createMockAttestation(2000n * 10n**18n)
// Works with MockPriceOracle on local Anvil — NOT for production

For production, the oracle service signs keccak256(abi.encodePacked(price, decimals, timestamp, assetPair)) with an authorized key. The PriceOracle contract validates this against Chainlink + Uniswap V3 (±5% deviation check on mainnet).

Contract Addresses

Addresses are loaded per chain ID:

import { getDeployment, getContractAddress } from '@permissionless-technologies/upd-sdk'

const deployment = getDeployment(1)       // mainnet (when deployed)
const updToken = getContractAddress(1, 'UPDToken')
const stabNFT = getContractAddress(1, 'StabilizerNFT')

To add a new chain, create src/deployments/[chainId].json with contract addresses.

React Hooks

Optional wagmi-based hooks for frontends:

import { useUPD, useCollateral, useStabilizer } from '@permissionless-technologies/upd-sdk/react'

function Dashboard() {
  const { balance, totalSupply, isLoading } = useUPD({ tokenAddress, userAddress })
  const { totalStEthCollateral, totalUPDSupply } = useCollateral({ reporterAddress, tokenAddress })
  const { positionEscrowAddress } = useStabilizer({ stabilizerNFTAddress, tokenId: 1n })
}

Contracts

| Contract | Purpose | |---|---| | UPDToken | Non-rebasing ERC20 ($1 = 1 UPD). Mint/burn via StabilizerNFT. | | StabilizerNFT | Entry point for minting/burning. Manages collateral allocation. | | PositionEscrow | Holds stETH per stabilizer. Yield increases collateral ratio. | | StabilizerEscrow | Holds unallocated stETH per stabilizer. | | PriceOracle | Validates signed ETH/USD attestations (Chainlink + Uniswap V3). | | OvercollateralizationReporter | System-wide collateral ratio tracking. |

ABIs

import {
  UPD_TOKEN_ABI, STABILIZER_NFT_ABI, PRICE_ORACLE_ABI,
  POSITION_ESCROW_ABI, STABILIZER_ESCROW_ABI,
} from '@permissionless-technologies/upd-sdk/contracts'

Subpath Exports

@permissionless-technologies/upd-sdk            # Everything
@permissionless-technologies/upd-sdk/core       # Client, types, quote, oracle
@permissionless-technologies/upd-sdk/contracts  # ABIs only
@permissionless-technologies/upd-sdk/react      # React hooks (wagmi)

Development

npm install          # Install deps
npm run build        # Build SDK (ESM + CJS + types)
npm test             # Run TypeScript tests (vitest)
npm run test:forge   # Run Solidity tests (forge)
npm run generate:abis # Rebuild ABIs from contracts