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

@dotpassport/sdk

v0.1.3

Published

Official JavaScript/TypeScript SDK for DotPassport API

Readme

DotPassport SDK

The Official JavaScript/TypeScript SDK for DotPassport - Web3 Reputation & Identity

npm version Bundle Size TypeScript License: MIT Tests Coverage

Getting Started • API Reference • Widgets • Examples • Contributing


What is DotPassport?

DotPassport is a comprehensive reputation and identity system for the Polkadot ecosystem. It aggregates on-chain activity across parachains to provide a unified reputation score, verifiable badges, and identity management for Web3 users.

This SDK provides:

  • API Client - Programmatic access to all DotPassport APIs
  • Embeddable Widgets - Ready-to-use UI components for displaying reputation data
  • Full TypeScript Support - Complete type definitions for type-safe development

Table of Contents


Quick Start

Install the SDK

npm install @dotpassport/sdk

Use the API Client

import { DotPassportClient } from '@dotpassport/sdk';

const client = new DotPassportClient({
  apiKey: 'your_api_key_here'
});

// Get user's reputation score
const scores = await client.getScores('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
console.log(`Total Score: ${scores.totalScore}`);

Embed a Widget

<div id="reputation-widget"></div>

<script type="module">
  import { createWidget } from '@dotpassport/sdk';

  createWidget({
    apiKey: 'your_api_key',
    address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
    type: 'reputation'
  }).mount('#reputation-widget');
</script>

That's it! You now have a fully functional reputation widget on your page.


Installation

NPM / Yarn / PNPM

# npm
npm install @dotpassport/sdk

# yarn
yarn add @dotpassport/sdk

# pnpm
pnpm add @dotpassport/sdk

CDN (Browser)

<script type="module">
  import { DotPassportClient, createWidget } from 'https://unpkg.com/@dotpassport/sdk/dist/index.js';
</script>

Requirements

| Requirement | Version | |-------------|---------| | Node.js | 16.0+ | | TypeScript | 5.0+ (optional) | | Browser | ES2020 compatible |


Environment Configuration

By default, the SDK connects to the production API (https://api.dotpassport.io). For local development, you have several options:

Option 1: Global Configuration (Recommended for Development)

import { setDefaultBaseUrl, LOCAL_URL } from '@dotpassport/sdk';

// Set at app startup - affects all subsequent client instances
setDefaultBaseUrl(LOCAL_URL); // 'http://localhost:4000'

// Or use a custom URL
setDefaultBaseUrl('https://staging.dotpassport.io');

Option 2: Per-Client Configuration

import { DotPassportClient } from '@dotpassport/sdk';

// Pass baseUrl when creating the client
const client = new DotPassportClient({
  apiKey: 'your_api_key',
  baseUrl: 'http://localhost:4000'  // Override default
});

Option 3: Environment Variable (Node.js only)

# Set before running your app
export DOTPASSPORT_API_URL=http://localhost:4000

Helper Functions

import {
  setDefaultBaseUrl,
  getDefaultBaseUrl,
  resetToProductionUrl,
  isLocalMode,
  LOCAL_URL,        // 'http://localhost:4000'
  PRODUCTION_URL    // 'https://api.dotpassport.io'
} from '@dotpassport/sdk';

// Check current mode
console.log(isLocalMode()); // true if using localhost

// Reset to production
resetToProductionUrl();

Features

🔌 Complete API Coverage

Access all DotPassport endpoints including profiles, scores, badges, and metadata.

const profile = await client.getProfile(address);
const scores = await client.getScores(address);
const badges = await client.getBadges(address);

🎨 Beautiful Embeddable Widgets

Drop-in widgets with zero configuration. Supports light/dark themes and full customization.

🛡️ Type-Safe Development

Written in TypeScript with complete type definitions. Catch errors at compile time.

🌳 Tree-Shakeable

Import only what you need. Unused code is automatically eliminated.

⚡ Lightweight & Fast

  • Core client: ~3KB gzipped
  • Each widget: ~5KB gzipped
  • Zero external dependencies (widgets)

🔄 Built-in Caching

Smart caching for widget data with configurable TTL to minimize API calls.


API Client

The DotPassportClient provides programmatic access to all DotPassport API endpoints.

Initialization

import { DotPassportClient } from '@dotpassport/sdk';

const client = new DotPassportClient({
  apiKey: 'live_your_api_key_here',    // Required
  baseUrl: 'https://api.dotpassport.xyz', // Optional (default)
  headers: {                            // Optional custom headers
    'X-Custom-Header': 'value'
  }
});

Profile Methods

// Get complete user profile
const profile = await client.getProfile(address);

// Response shape
{
  address: '5Grwva...',
  displayName: 'Alice',
  bio: 'Polkadot enthusiast',
  avatar: 'https://...',
  socials: {
    twitter: '@alice',
    github: 'alice-dev'
  },
  identities: [
    { chain: 'polkadot', verified: true }
  ]
}

Score Methods

// Get all scores for a user
const scores = await client.getScores(address);

// Response shape
{
  address: '5Grwva...',
  totalScore: 850,
  categories: [
    { key: 'longevity', title: 'Account Longevity', score: 100, maxScore: 100 },
    { key: 'governance', title: 'Governance', score: 75, maxScore: 100 },
    // ... more categories
  ]
}

// Get specific category score
const category = await client.getCategoryScore(address, 'governance');

Badge Methods

// Get all badges for a user
const badges = await client.getBadges(address);

// Response shape
{
  address: '5Grwva...',
  badges: [
    {
      badgeKey: 'early_adopter',
      achievedLevel: 3,
      achievedLevelKey: 'gold',
      achievedLevelTitle: 'Gold Early Adopter',
      earnedAt: '2024-01-15T10:30:00Z'
    }
  ],
  count: 5
}

// Get specific badge
const badge = await client.getBadge(address, 'early_adopter');

Metadata Methods

// Get all badge definitions
const badgeDefs = await client.getBadgeDefinitions();

// Get all category definitions
const categoryDefs = await client.getCategoryDefinitions();

AbortSignal Support

All methods support AbortSignal for request cancellation:

const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

const scores = await client.getScores(address, { signal: controller.signal });

Embeddable Widgets

DotPassport SDK includes four beautiful, customizable widgets that work with any framework.

Widget Types

| Widget | Description | Use Case | |--------|-------------|----------| | Reputation | Total score with category breakdown | User dashboards, profiles | | Badge | Earned badges display | Achievement showcases | | Profile | User profile card | Social features, identity | | Category | Single category deep-dive | Detailed score analysis |


Widget Gallery

Reputation Widget

Displays total reputation score with category breakdown

import { createWidget } from '@dotpassport/sdk';

createWidget({
  apiKey: 'your_api_key',
  address: 'polkadot_address',
  type: 'reputation',
  theme: 'light',           // 'light' | 'dark' | 'auto'
  showCategories: true,     // Show category breakdown
  maxCategories: 6,         // Limit visible categories
  compact: false,           // Compact mode
  onLoad: () => console.log('Loaded!'),
  onError: (err) => console.error(err)
}).mount('#reputation-widget');

Badge Widget

Shows badges earned by the user

createWidget({
  apiKey: 'your_api_key',
  address: 'polkadot_address',
  type: 'badge',
  theme: 'dark',
  maxBadges: 6,            // Maximum badges to show
  showProgress: true,       // Show earned date
  badgeKey: 'early_adopter' // Optional: show single badge
}).mount('#badge-widget');

Profile Widget

User profile card with social links and identities

createWidget({
  apiKey: 'your_api_key',
  address: 'polkadot_address',
  type: 'profile',
  theme: 'light',
  showAvatar: true,        // Display avatar
  showBio: true,           // Display bio
  showSocials: true,       // Display social links
  showIdentities: true     // Display chain identities
}).mount('#profile-widget');

Category Widget

Detailed breakdown of a specific reputation category

createWidget({
  apiKey: 'your_api_key',
  address: 'polkadot_address',
  type: 'category',
  categoryKey: 'governance', // Required: category to display
  theme: 'light',
  showTitle: true,          // Show category title
  showDescription: true,    // Show category description
  showBreakdown: true,      // Show score breakdown
  showAdvice: true,         // Show improvement tips
  showScoreOnly: false      // Minimal score-only view
}).mount('#category-widget');

Configuration Reference

Common Widget Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | required | Your DotPassport API key | | address | string | required | Polkadot address to display | | type | string | 'reputation' | Widget type | | theme | 'light' \| 'dark' \| 'auto' | 'light' | Color theme | | compact | boolean | false | Compact display mode | | className | string | '' | Custom CSS class | | onLoad | () => void | - | Callback when loaded | | onError | (error: Error) => void | - | Error callback |

Reputation Widget Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | showCategories | boolean | true | Show category breakdown | | maxCategories | number | 6 | Max categories to display |

Badge Widget Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | badgeKey | string | - | Show single specific badge | | maxBadges | number | 10 | Max badges to display | | showProgress | boolean | true | Show earned dates |

Profile Widget Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | showAvatar | boolean | true | Display user avatar | | showBio | boolean | true | Display user bio | | showSocials | boolean | true | Display social links | | showIdentities | boolean | true | Display chain identities |

Category Widget Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | categoryKey | string | required | Category key to display | | showTitle | boolean | true | Show category title | | showDescription | boolean | true | Show description | | showBreakdown | boolean | true | Show score breakdown | | showAdvice | boolean | true | Show improvement tips | | showScoreOnly | boolean | false | Minimal view |


Framework Integration

React

import { useEffect, useRef } from 'react';
import { createWidget, type WidgetConfig } from '@dotpassport/sdk';

interface DotPassportWidgetProps extends WidgetConfig {
  className?: string;
}

export function DotPassportWidget({ className, ...config }: DotPassportWidgetProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const widgetRef = useRef<ReturnType<typeof createWidget>>();

  useEffect(() => {
    if (!containerRef.current) return;

    // Create and mount widget
    widgetRef.current = createWidget(config);
    widgetRef.current.mount(containerRef.current);

    // Cleanup on unmount
    return () => {
      widgetRef.current?.destroy();
    };
  }, []);

  // Handle config updates
  useEffect(() => {
    widgetRef.current?.update(config);
  }, [config.address, config.theme]);

  return <div ref={containerRef} className={className} />;
}

// Usage
function App() {
  return (
    <DotPassportWidget
      apiKey="your_api_key"
      address="5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
      type="reputation"
      theme="dark"
      showCategories={true}
    />
  );
}

Vue 3

<template>
  <div ref="container" :class="className"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';
import { createWidget, type WidgetConfig } from '@dotpassport/sdk';

interface Props extends WidgetConfig {
  className?: string;
}

const props = defineProps<Props>();
const container = ref<HTMLElement>();
let widget: ReturnType<typeof createWidget>;

onMounted(() => {
  if (container.value) {
    widget = createWidget(props);
    widget.mount(container.value);
  }
});

onUnmounted(() => {
  widget?.destroy();
});

watch(
  () => [props.address, props.theme],
  () => {
    widget?.update(props);
  }
);
</script>

Svelte

<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import { createWidget, type WidgetConfig } from '@dotpassport/sdk';

  export let apiKey: string;
  export let address: string;
  export let type: WidgetConfig['type'] = 'reputation';
  export let theme: WidgetConfig['theme'] = 'light';

  let container: HTMLElement;
  let widget: ReturnType<typeof createWidget>;

  onMount(() => {
    widget = createWidget({ apiKey, address, type, theme });
    widget.mount(container);
  });

  onDestroy(() => {
    widget?.destroy();
  });

  $: if (widget) {
    widget.update({ address, theme });
  }
</script>

<div bind:this={container}></div>

Vanilla JavaScript

<!DOCTYPE html>
<html>
<head>
  <title>DotPassport Widget Demo</title>
</head>
<body>
  <div id="reputation-widget"></div>
  <button id="toggle-theme">Toggle Theme</button>

  <script type="module">
    import { createWidget } from '@dotpassport/sdk';

    let currentTheme = 'light';

    const widget = createWidget({
      apiKey: 'your_api_key',
      address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
      type: 'reputation',
      theme: currentTheme,
      onLoad: () => console.log('Widget loaded successfully!'),
      onError: (error) => console.error('Widget error:', error)
    });

    widget.mount('#reputation-widget');

    // Theme toggle
    document.getElementById('toggle-theme').addEventListener('click', () => {
      currentTheme = currentTheme === 'light' ? 'dark' : 'light';
      widget.update({ theme: currentTheme });
    });
  </script>
</body>
</html>

Wallet Integration

Connect DotPassport SDK with popular Polkadot wallets to display reputation data for connected users.

Talisman Wallet

import { getWallets } from '@talismn/connect-wallets';
import { DotPassportClient, createWidget } from '@dotpassport/sdk';

// 1. Connect to Talisman
const wallets = getWallets();
const talisman = wallets.find(w => w.extensionName === 'talisman');
await talisman.enable('My App');
const accounts = await talisman.getAccounts();
const address = accounts[0].address;

// 2. Use with DotPassport API
const client = new DotPassportClient({ apiKey: 'your_key' });
const scores = await client.getScores(address);
console.log(`Reputation: ${scores.totalScore}`);

// 3. Or use with Widgets
const widget = createWidget({
  apiKey: 'your_key',
  address: address,
  type: 'reputation'
});
widget.mount('#widget');

// 4. Update widget when account changes
talisman.subscribeAccounts((accounts) => {
  widget.update({ address: accounts[0].address });
});

SubWallet

import { getWalletBySource, isWalletInstalled } from '@subwallet/wallet-connect';
import { DotPassportClient, createWidget } from '@dotpassport/sdk';

// 1. Check and connect to SubWallet
const installed = await isWalletInstalled('subwallet-js');
if (!installed) {
  window.open('https://subwallet.app', '_blank');
}

const wallet = await getWalletBySource('subwallet-js');
await wallet.enable();
const accounts = await wallet.getAccounts();
const address = accounts[0].address;

// 2. Use with DotPassport API
const client = new DotPassportClient({ apiKey: 'your_key' });
const scores = await client.getScores(address);

// 3. Or use with Widgets
const widget = createWidget({
  apiKey: 'your_key',
  address: address,
  type: 'reputation',
  theme: 'dark'
});
widget.mount('#widget');

// 4. Subscribe to account changes
await wallet.subscribeAccounts((accounts) => {
  if (accounts.length > 0) {
    widget.update({ address: accounts[0].address });
  }
});

React Hook Example

import { useState, useEffect, useRef } from 'react';
import { getWallets } from '@talismn/connect-wallets';
import { createWidget } from '@dotpassport/sdk';

function useDotPassportWallet(apiKey: string) {
  const [address, setAddress] = useState<string | null>(null);
  const widgetRef = useRef<ReturnType<typeof createWidget>>();
  const containerRef = useRef<HTMLDivElement>(null);

  const connect = async () => {
    const wallets = getWallets();
    const talisman = wallets.find(w => w.extensionName === 'talisman');
    await talisman?.enable('My App');
    const accounts = await talisman?.getAccounts();
    if (accounts?.[0]) {
      setAddress(accounts[0].address);
    }
  };

  useEffect(() => {
    if (!address || !containerRef.current) return;

    widgetRef.current = createWidget({
      apiKey,
      address,
      type: 'reputation'
    });
    widgetRef.current.mount(containerRef.current);

    return () => widgetRef.current?.destroy();
  }, [address, apiKey]);

  return { connect, address, containerRef };
}

// Usage
function App() {
  const { connect, address, containerRef } = useDotPassportWallet('your_key');

  return (
    <div>
      {!address ? (
        <button onClick={connect}>Connect Wallet</button>
      ) : (
        <div ref={containerRef} />
      )}
    </div>
  );
}

📖 Detailed Wallet Guides:


Custom Styling

Widgets support CSS variable overrides for custom styling:

/* Override widget theme colors */
.my-custom-widget {
  --dp-primary: #8b5cf6;
  --dp-secondary: #ec4899;
  --dp-bg: #ffffff;
  --dp-bg-secondary: #f9fafb;
  --dp-text-primary: #111827;
  --dp-text-secondary: #6b7280;
  --dp-border: #e5e7eb;
  --dp-border-radius: 12px;
  --dp-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}

/* Dark theme overrides */
.my-custom-widget.dp-theme-dark {
  --dp-bg: #1f2937;
  --dp-bg-secondary: #374151;
  --dp-text-primary: #f9fafb;
  --dp-text-secondary: #9ca3af;
  --dp-border: #4b5563;
}

Error Handling

The SDK provides structured error handling through DotPassportError:

import { DotPassportClient, DotPassportError } from '@dotpassport/sdk';

const client = new DotPassportClient({ apiKey: 'your_key' });

try {
  const scores = await client.getScores('invalid-address');
} catch (error) {
  if (error instanceof DotPassportError) {
    console.error('Status:', error.statusCode);    // 404
    console.error('Message:', error.message);       // "User not found"
    console.error('Response:', error.response);     // Full error response

    // Handle specific errors
    switch (error.statusCode) {
      case 401:
        console.error('Invalid API key');
        break;
      case 404:
        console.error('User not found');
        break;
      case 429:
        console.error('Rate limit exceeded');
        break;
      default:
        console.error('Unknown error');
    }
  }
}

Error Codes Reference

| Code | Name | Description | |------|------|-------------| | 400 | Bad Request | Invalid request parameters | | 401 | Unauthorized | Invalid or missing API key | | 403 | Forbidden | Access denied to resource | | 404 | Not Found | User, badge, or category not found | | 429 | Too Many Requests | Rate limit exceeded | | 500 | Server Error | Internal server error |


TypeScript Support

The SDK is written in TypeScript with complete type definitions.

Importing Types

import type {
  // Client configuration
  DotPassportConfig,

  // API response types
  UserProfile,
  UserScores,
  UserBadges,
  CategoryScore,
  BadgeDefinition,
  CategoryDefinition,

  // Widget configuration
  WidgetConfig,
  ReputationWidgetConfig,
  BadgeWidgetConfig,
  ProfileWidgetConfig,
  CategoryWidgetConfig,

  // Error type
  DotPassportError
} from '@dotpassport/sdk';

Type-Safe Usage

import { DotPassportClient, type UserScores, type UserBadges } from '@dotpassport/sdk';

const client = new DotPassportClient({ apiKey: 'your_key' });

// Fully typed responses
const scores: UserScores = await client.getScores(address);
scores.totalScore;      // ✅ number
scores.categories;      // ✅ CategoryScore[]
scores.invalid;         // ❌ TypeScript error

const badges: UserBadges = await client.getBadges(address);
badges.count;           // ✅ number
badges.badges[0].badgeKey; // ✅ string

Examples

Complete Dashboard Example

import { DotPassportClient, createWidget } from '@dotpassport/sdk';

const API_KEY = 'your_api_key';
const ADDRESS = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';

// Initialize client for API calls
const client = new DotPassportClient({ apiKey: API_KEY });

// Fetch and display data programmatically
async function loadDashboard() {
  const [profile, scores, badges] = await Promise.all([
    client.getProfile(ADDRESS),
    client.getScores(ADDRESS),
    client.getBadges(ADDRESS)
  ]);

  console.log(`Welcome, ${profile.displayName}!`);
  console.log(`Your reputation score: ${scores.totalScore}`);
  console.log(`Badges earned: ${badges.count}`);
}

// Create widgets for visual display
const reputationWidget = createWidget({
  apiKey: API_KEY,
  address: ADDRESS,
  type: 'reputation',
  theme: 'auto',
  showCategories: true
});

const badgeWidget = createWidget({
  apiKey: API_KEY,
  address: ADDRESS,
  type: 'badge',
  maxBadges: 4
});

const profileWidget = createWidget({
  apiKey: API_KEY,
  address: ADDRESS,
  type: 'profile'
});

// Mount widgets
reputationWidget.mount('#reputation-section');
badgeWidget.mount('#badges-section');
profileWidget.mount('#profile-section');

// Handle address changes
function updateAddress(newAddress: string) {
  reputationWidget.update({ address: newAddress });
  badgeWidget.update({ address: newAddress });
  profileWidget.update({ address: newAddress });
}

Widget with Event Handling

const widget = createWidget({
  apiKey: 'your_key',
  address: 'polkadot_address',
  type: 'reputation',
  onLoad: () => {
    console.log('Widget loaded successfully');
    document.getElementById('loading')?.remove();
  },
  onError: (error) => {
    console.error('Widget failed to load:', error);
    document.getElementById('widget-container')!.innerHTML = `
      <div class="error">Failed to load reputation data</div>
    `;
  }
});

widget.mount('#widget-container');

// Later: refresh data
document.getElementById('refresh-btn')?.addEventListener('click', () => {
  widget.refresh();
});

// Later: cleanup
window.addEventListener('beforeunload', () => {
  widget.destroy();
});

Testing

The SDK includes comprehensive test coverage with 236+ tests.

Running Tests

# Run all tests
npm test

# Run with coverage report
npm run test:coverage

# Run in watch mode
npm run test:watch

# Run only unit tests
npm run test:unit

# Run only integration tests
npm run test:integration

Coverage

| Metric | Coverage | |--------|----------| | Statements | 86%+ | | Branches | 86%+ | | Functions | 86%+ | | Lines | 86%+ |


Contributing

We welcome contributions from the community! Here's how you can help:

Ways to Contribute

  • 🐛 Report Bugs - Open an issue with a clear description
  • 💡 Suggest Features - Share your ideas for improvements
  • 📝 Improve Docs - Help make our documentation better
  • 🔧 Submit PRs - Fix bugs or add new features

Development Setup

# 1. Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/sdk.git
cd sdk

# 2. Install dependencies
npm install

# 3. Run tests to ensure everything works
npm test

# 4. Start development
npm run build

Code Style

  • We use ESLint and Prettier for code formatting
  • Write TypeScript with strict type checking
  • Add tests for new features
  • Update documentation for API changes

Pull Request Process

  1. Create a feature branch: git checkout -b feature/amazing-feature
  2. Make your changes and commit: git commit -m 'Add amazing feature'
  3. Push to your fork: git push origin feature/amazing-feature
  4. Open a Pull Request with a clear description

Commit Convention

We follow Conventional Commits:

feat: add new badge widget animation
fix: resolve theme switching bug
docs: update API reference
test: add integration tests for profile widget
refactor: improve widget rendering performance

Author

Sachin

GitHub Twitter

Building the future of Web3 identity and reputation


License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2024 DotPassport

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software...

Links

| Resource | Link | |----------|------| | 📦 NPM Package | npmjs.com/@dotpassport/sdk | | 📖 Documentation | docs.dotpassport.xyz | | 🌐 Website | dotpassport.xyz | | 🐛 Issues | GitHub Issues | | 💬 Discord | Join our community |


⬆ Back to Top


Made with ❤️ by the DotPassport Team

Empowering Web3 identity and reputation