npm package: @jonheaven/dogestash
Description: Dogecoin wallet toolkit with browser wallet core, adapters, and React integrations.
Latest version: 1.1.1
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# @jonheaven/dogestash

Dogecoin local browser wallet implementation plus browser extension support for DOGE dApps.


Provides a self-contained wallet toolkit for building on Dogecoin:
- Local browser wallet core (`BrowserWallet`)
- Wallet adapters and unified wallet flows for DOGE L1 wallets: MyDoge, Dojak
- React contexts for wallet state (`src/contexts`)
- Wallet connect and wallet management UI components (`src/components`)

## What is included
- Dogecoin browser wallet generation, import, and storage
- Web Crypto encrypted local wallet storage with automatic legacy migration
- Ledger hardware wallet support for mainnet Dogecoin accounts
- Secure seed backup/export with QR support for encrypted mnemonic wallets
- HD multi-account switching on Dogecoin BIP-44 accounts
- Unified wallet context patterns for browser and extension wallets
- Connect modal and wallet management modal UI

## Security & Best Practices
- Industry-standard Web Crypto API encryption (PBKDF2 + AES-GCM) protects password-backed browser wallets. Existing encrypted wallets are automatically decrypted with the legacy format and re-encrypted with the current Web Crypto envelope on first successful unlock.
- Ledger hardware wallet is supported and presented as the recommended primary wallet path for long-term storage and signing isolation.
- All wallet data is fetched from your own kabosu-compatible indexer. No third-party RPCs are required by `@jonheaven/dogestash`.
- Browser wallet recovery phrases can be exported with explicit warnings, QR backup, and HD account recovery metadata. If a BIP-39 passphrase is used, include it with the mnemonic backup.
- Keep browser-wallet passwords unique, back up seed material offline before funding, and prefer a Ledger for treasury or high-value wallets.

## Install

```bash
npm install @jonheaven/dogestash
```

## Hello World React dApp

```tsx
import React from 'react';
import {
  DogestashProvider,
  ConnectWalletButton,
  useUnifiedWallet,
} from '@jonheaven/dogestash';

function HelloWorldApp() {
  return (
    <DogestashProvider>
      <HelloWorld />
    </DogestashProvider>
  );
}

function HelloWorld() {
  const { connected, address, balance, balanceVerified, signMessage } = useUnifiedWallet();

  const handleSign = async () => {
    try {
      const signed = await signMessage('Hello, Dogecoin World!');
      alert(`Signed message: ${signed}`);
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Unknown error';
      alert(`Error: ${message}`);
    }
  };

  return (
    <div style={{ padding: 20, textAlign: 'center' }}>
      <h1>Dogestash Hello World</h1>
      <ConnectWalletButton />
      {connected ? (
        <>
          <p>Connected Address: {address}</p>
          <p>Balance: {balanceVerified ? `${balance} DOGE` : 'Loading...'}</p>
          <button onClick={handleSign}>Sign "Hello, Dogecoin World!"</button>
        </>
      ) : (
        <p>Connect a wallet to get started.</p>
      )}
    </div>
  );
}

export default HelloWorldApp;
```

This is the minimal supported flow today: connect a DOGE L1 wallet, read the connected address and verified balance from context, and sign a message with one hook call.

For custom UIs, keep `DogestashProvider` at the app root and use `useUnifiedWallet()` directly.

## Public API

Primary exports from `@jonheaven/dogestash`:
- `BrowserWallet`
- `BrowserWalletSigner`
- `DogestashProvider`
- `useBrowserWallet`
- `useUnifiedWallet`
- `ConnectWalletButton`
- `WalletSelectionModal`

Recommended subpath imports for maximum tree-shaking:

```ts
import { BrowserWallet } from '@jonheaven/dogestash/lib/browser-wallet';
import { BrowserWalletSigner } from '@jonheaven/dogestash/adapters/BrowserWalletSigner';
import { DogestashProvider } from '@jonheaven/dogestash/providers/DogestashProvider';
```

## Marketplace Signer Quickstart

```ts
import { BrowserWallet, BrowserWalletSigner } from '@jonheaven/dogestash';

const browserWallet = new BrowserWallet();
const created = await BrowserWallet.generateWallet('mainnet');
await browserWallet.saveWallet(created, 'strong-password');

const signer = new BrowserWalletSigner(browserWallet, 'strong-password');
await signer.connect();

const signature = await signer.signIntent({
  intentType: 'listing_buy',
  nonce: crypto.randomUUID(),
  expiresAt: new Date(Date.now() + 60_000).toISOString(),
  network: 'mainnet',
  chainId: 'doge-mainnet',
  address: created.address,
  listingId: 'listing_123',
});

console.log(signature);
```

Notes:
- `signIntent` validates `expiresAt`, `network`, and `address` before signing.
- Storage namespace is `dogestash_wallet_*`; legacy `dogemarket_browser_wallet_*` keys auto-migrate on first use.

## DoginalMarket Protocol (DMP)

Use `useUnifiedWallet()` with `ConnectWalletButton` to produce kabosu-compatible DMP payloads in one call.

```tsx
const { signDMPIntent } = useUnifiedWallet();

const signedIntent = await signDMPIntent('listing', {
  price_koinu: 4206900000,
  psbt_cid: 'ipfs://Qm...',
  expiry_height: 5000000,
});

const signedBid = await signDMPIntent('bid', {
  listing_id: '<listing-inscription-id>',
  price_koinu: 4206900000,
  psbt_cid: 'ipfs://Qm...',
  expiry_height: 5000100,
});
```

Returned payloads already use the canonical DMP wire format expected by kabosu:
- `protocol: "DMP"`
- `version: "1.0"`
- `op: "listing" | "bid" | "settle" | "cancel"`
- `seller`, `nonce`, and hex `signature` are filled automatically from the connected wallet

## DMP Marketplace Demo (Quickstart)

A minimal end-to-end example lives in [`src/examples/DMPDemo.tsx`](src/examples/DMPDemo.tsx).

It shows how to:
- connect a wallet with `dogestash`
- enter `price_koinu` and `expiry_height`
- sign a sample `listing` intent with `signDMPIntent('listing', ...)`
- sign a sample `bid` intent with `signDMPIntent('bid', ...)`
- inspect the returned signed DMP JSON in the UI

## Indexer / Data Provider API

`@jonheaven/dogestash` makes no direct calls to any third-party service. All chain data (balances, UTXOs, inscriptions, DRC-20 tokens) is fetched through a single configurable base URL pointing at your own deployed indexer.

The workflow:
1. Deploy [**jonheaven/dog**](https://github.com/jonheaven/dog) or [**jonheaven/kabosu**](https://github.com/jonheaven/kabosu) to a server, for example `https://api.yourdomain.com`
2. Set the env var in your frontend:
   ```env
   VITE_WALLET_DATA_API_BASE_URL=https://api.yourdomain.com/api
   ```
3. `@jonheaven/dogestash` will route all wallet data fetches through that endpoint with no third-party dependencies.

Defaults to `http://localhost:3001/api` if unset, which works out of the box when running either reference indexer locally during development.

### Required endpoints

All endpoints accept `address` as a query parameter and return JSON.

#### `GET /indexer/balance?address=<addr>`

Returns the spendable DOGE balance for an address.

```jsonc
// Expected response (any of these shapes works):
{ "balanceSatoshis": 500000000 }
{ "balance": 500000000 }
{ "availableBalance": 500000000 }
```

Balance is interpreted as satoshis and converted to DOGE internally (`/ 100,000,000`).

#### `GET /indexer/utxos?address=<addr>`

Returns unspent outputs needed for transaction construction.

```jsonc
// Expected response: array of UTXOs
[
  {
    "txid": "abc123...",
    "vout": 0,
    "value": 100000000,
    "scriptPubKey": "76a914..."
  }
]
```

The exact UTXO shape is passed through to the PSBT builder as-is. Match whatever your signing flow expects.

#### `GET /indexer/inscriptions?address=<addr>`

Returns Doginal inscriptions held by an address.

```jsonc
// Expected response (any of these shapes works):
{ "list": [ { "inscriptionId": "...", "contentType": "image/png" } ] }
{ "items": [ ... ] }
{ "data": [ ... ] }
[ ... ]
```

Each item should include at minimum `inscriptionId`, `contentType`, `genesisTransaction`, and `inscriptionNumber`.

#### `GET /indexer/drc20?address=<addr>`

Returns DRC-20 token balances for an address.

```jsonc
// Expected response (any of these shapes works):
{
  "balances": [
    {
      "ticker": "DOGI",
      "availableBalance": "1000",
      "transferableBalance": "500",
      "overallBalance": "1500"
    }
  ]
}
// Also accepted: { "tokens": [...] } or a bare array
```

Fields are normalized internally. `balance`, `available`, and `transferable` shorthand keys are also recognized.

### Optional endpoints

| Endpoint | Used by |
|---|---|
| `GET /health` | `StatusIndicator` component for green/red connection state |
| `GET /claims/active?address=<addr>` | `ClaimModal` component |
| `POST /launches/:id/claim` | Dogedrops claim flow |

### Reference implementations

- [**jonheaven/dog**](https://github.com/jonheaven/dog)
- [**jonheaven/kabosu**](https://github.com/jonheaven/kabosu)

Either implements all required and optional endpoints and is designed to be deployed alongside this library.

### Mapping to other providers

| Provider | Notes |
|---|---|
| [QuickNode Dogecoin](https://www.quicknode.com/) | Proxy `/indexer/*` to their RPC methods |
| [Dogechain.info API](https://dogechain.info/api/v1/) | Thin adapter. Field names differ slightly |
| Self-hosted [ord](https://github.com/ordinals/ord) | Inscriptions endpoint maps directly |
| Custom backend | Implement the four endpoints and return any of the accepted shapes |