# Welcome to Interstellar Docs

D3 is the first authoritative network built for DomainFi that tokenizes domains as real-world assets for billions of users on the root layer of the internet.&#x20;

### What is DomainFi?

[DomainFi](https://d3.inc/blog/editorials/unleashing-the-future-of-the-internet-with-domainfi/) represents a vision for a decentralized internet where users have true ownership and control over domains as their digital identities. DomainFi requires a network designed to tokenize current and future domain names, enabling fast, secure, and low-cost transactions while unlocking new financial opportunities. By tokenizing domains as real-world assets, DomainFi will enable individuals and organizations to buy, sell, and manage their domains with more security, transparency, and liquidity. Once domains become verifiable digital assets onchain, they behave more like other financial assets that can be quickly transferred, traded, and even used in advanced financial markets. Tokenized domains can then be fractionalized, staked, or bundled into different financial products, enhancing the utility and accessibility of domain ownership.

Whether you’re an experienced blockchain developer or just starting out, D3 provides you with the resources, tools, and community support to succeed with DomainFi.

### Get Started Today

Dive right in to start building for DomainFi:

1. Resolve Names with DNS Connect\
   Use our DNS Connect tools to access both traditional and Web3 domain resolution. Handle name resolution for your applications using DNS and ENS in a unified, simple framework.\
   👉 [Learn more about DNS Connect](/resolve-d3-names)
2. Integrate Name Token Sales\
   Add Name Token sales directly into your platform. Use our public APIs to allow users to search, purchase, and mint Name Tokens while managing the experience within your app.\
   👉[ Explore the D3 API](https://docs.d3.app/integrate-d3-name-token-sales/d3-api)

You can also [explore commercial opportunities as a D3 affiliate channel partner](https://d3.inc/partner/) and make money by integrating features to sell name tokens in your apps.

### Why Build with D3?

#### **Build Once, Integrate Everywhere**

Get name resolution services for traditional internet and Web3 in one place, including out-of-the-box support for DNS and ENS. Use a single integration without the need for endless SDKs, APIs, or hacks.

#### **Futureproof By Design**

Use tools and languages you already know and love. Access secure and compliant infrastructure that is forward and backward compatible.

#### **Monetize Domains**

Generate revenue as an affiliate partner by selling name tokens from within your apps. Give users the ability to search, purchase, and mint name tokens while maintaining full control over the user experience.

###


# Resolve D3 Names

## Building With DNS Connect SDK <a href="#resolution-sdk" id="resolution-sdk"></a>

### Overview <a href="#resolution-sdk" id="resolution-sdk"></a>

The DNS Connect SDK aims to bring different Web3 Name Resolution services under one umbrella to simplify integration efforts for developers. It supports the following resolution methods, which can be applied in order of priority:

1. DNS Resolution
2. (Optional) ENS resolution
3. (Optional) Other resolution services - either provided by D3 or community.

<img src="/files/Vud0wYZUfSzsZNBL0Q51" alt="" class="gitbook-drawing">

### Why Use DNS Connect SDK

DNS Connect SDK offers a host of benefits including:

* Seamless transition between existing web (Internet) and Web3 infrastructure
* Futureproof design with backward and forward compatibility at its foundation
* Single integration without the need for endless SDKs, APIs and more
* Accessible, compliant and secure infrastructure

## SDK Documentation and Sample Code

DNS Connect is a unified JavaScript SDK to resolve Web3 names, built to be modular in nature and consisting of several resolution modules, which are applied in order of priority:

* **DNS resolution module**. Resolves Web3 names using DNS TXT records. This is a core module, which cannot be disabled and always applied first.
* **ENS resolution module**. Resolves Web3 names using [ENS](https://ens.domains/). Distributed as a separate `@webinterop/dns-connect-ens` package.
* Other modules...

DNS Connect SDK can be used in both NodeJS and browser environments:

* Node 18+ (`fetch` api support is needed, this might be relaxed in future).
* Browsers with ES2022 features support (basically all modern browsers).

#### `@webinterop/dns-connect`

This package provides a modular SDK itself and a DNS resolution module. It is a lightweight zero-dependency library, which can be used to perform basic Web3 Wallet address resolution using standard DNS protocol.

{% tabs %}
{% tab title="NPM" %}

```sh
npm install @webinterop/dns-connect
```

{% endtab %}

{% tab title="Yarn" %}

```sh
yarn add @webinterop/dns-connect
```

{% endtab %}
{% endtabs %}

The SDK provides two methods for performing forward and reverse name resolution:

```javascript
/**
 * Resolves a name to an address.
 * @param name - The name to resolve.
 * @param network - The network to resolve the name on.
 * @returns The resolved address.
 */
async resolve(name: string, network: string): Promise<string | undefined>

/**
 * Resolves an address to a name.
 * @param address - The address to resolve.
 * @param network - The network to resolve the address on.
 * @returns The resolved name.
 */
async reverseResolve(address: string, network: string): Promise<string | undefined>
```

A basic example is shown below:

```javascript
import { DNSConnect } from '@webinterop/dns-connect';

const dnsConnect = new DNSConnect();

// Resolves `example.core` name on `CORE` blockchain
const walletAddress = await dnsConnect.resolve('example.core', 'CORE');
console.log(walletAddress);

// Reverse resolves wallet address `0xaaaa` on `CORE` blockchain
const domainName = await dnsConnect.reverseResolve('0xaaaa', 'CORE');
console.log(domainName);
```

Our SDK is highly configurable, and can be customized for a variety of use cases:

```javascript
const dnsConnect = new DNSConnect({
  // DNS resolution module options (with defaults):
  dns: {
    forwarderDomain: 'forwarder.d3.app',
    // Whether or not DNSSEC verification must be performed by a resolver
    dnssecVerification: true,
    // DNS-over-HTTPS resolver is provided by default. It uses dns-json format, which is supported by CloudFlare & Google resolvers.
    // This could be substituted with different implementations by SDK consumers.
    resolver: new DNSOverHTTPSResolver({
      dnsServer: 'https://cloudflare-dns.com/dns-query',
    }),
  },
  // Log level for the SDK log messages
  logLevel: 'info', // "trace" | "info" | "warn" | "error" | "silent"
  // If needed, custom logger implementation can be provided.
  // By default, standard console logger is used.
  logger: <ConsoleLogger>,
  // In-memory cache is used by default to cache resolution result (and intermediate resolution data)
  // To avoid memory leaks (in server scenarios), or use persistent cache (in browser scenarios), custom caching implementation can be provided.
  caching: {
    enabled: true,
    cacheProvider: <InMemoryCache>,
  },
});
```

Below is the list of supported Blockchain networks (passed as the second parameter to the `resolve` and `reverseResolve` methods):

| Blockchain | Network parameter |
| ---------- | ----------------- |
| Ethereum   | ETH               |
| Bitcoin    | BTC               |
| Shibarium  | BONE              |
| Core       | CORE              |
| Viction    | VIC               |
| Polygon    | MATIC             |
| Cardano    | ADA               |
| ApeChain   | APE               |

**Current version limitations:**

1. IDNA (Unicode) names resolution is not supported, names should be normalized and converted to [Punycode](https://en.wikipedia.org/wiki/Punycode) before passing to SDK.
2. Retries are not implemented for DNS queries.
3. Need to provide a common interface to pass cross-cutting services (caching, logging) to the modules.
4. `logLevel` is not respected for external logger. Need to use an internal logging abstraction.
5. `network` argument is not properly validated. [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) validation can be added.

#### `@webinterop/dns-connect-ens`

This is an optional module which adds support for ENS names resolution.

{% tabs %}
{% tab title="NPM" %}

```sh
npm install @webinterop/dns-connect-ens
```

{% endtab %}

{% tab title="Yarn" %}

```sh
yarn add @webinterop/dns-connect-ens
```

{% endtab %}
{% endtabs %}

Basic usage:

```javascript
import { DNSConnect } from '@webinterop/dns-connect';
import { ENSModule } from '@webinterop/dns-connect-ens';

const dnsConnect = new DNSConnect({ modules: [new ENSModule()] });
const walletAddress = await d3Connect.resolve('test.eth', 'ETH');
console.log(walletAddress);
```

Under the hood, it uses the `@ensdomains/ensjs` package, which in turn uses `viem` for blockchain integration. Viem chain and transport can be provided to further customize this module:

```javascript
import { DNSConnect } from '@webinterop/dns-connect';
import { ENSModule } from '@webinterop/dns-connect-ens';
import { http } from 'viem';
import { mainnet } from 'viem/chains';

const dnsConnect = new DNSConnect({
  modules: [
    new ENSModule({
      // Be default, `viem` Ethereum Mainnet network is used.
      // Custom network can be provided for testnet or private deployments.
      chain: mainnet,
      // By default, HTTP transport used
      transport: http(),
    }),
  ],
});
```

**Current** version limitations:

1. ENS TTL is currently not used, so resolution results are not cached. Internal `@ensdomains/ensjs` is used instead.
2. Provided `network` is not validated for support by `@ensdomains/ensjs`.

#### Custom resolution modules

Custom resolution modules can be written by implementing the `DNSConnectModule` interface:

```javascript
export interface CustomModuleOptions {
  // Module options here
}

export class CustomModule implements DNSConnectModule {
  // Name is used for logging purposes
  name = 'MyModuleName';

  constructor(options?: CustomModuleOptions) {
    // Initialize your module
  }

  async resolve(name: string, network: string): Promise<ResolutionResult | undefined> {
    // Perform resolution of the provided name using custom logic.
    // If name cannot be resolved by this module, return `undefined`.

    return {
      // Return resolved wallet address (MUST not be empty)
      address: resolvedAddress,
      // Return TTL for resolved address (in seconds)
      // 0 can be returned to disable caching for this name
      ttl: 30,
    };
  }
  
  async reverseResolve(address: string, network: string): Promise<ReverseResolutionResult | undefined> {
   // Perform reverse resolution of the provided address using custom logic.
   // If address cannot be reverse resolved by this module, return `undefined`.

   return {
     // Return reverse resolved name (MUST not be empty)
     name: resolvedName,
     // Return TTL for resolved address (in seconds)
     // 0 can be returned to disable caching for this name
     ttl: 30,
   };

}
```

To use it, pass it as a module in `DNSConnect` options:

```javascript
import { DNSConnect } from '@webinterop/dns-connect';

const dnsConnect = new DNSConnect({ modules: [new CustomModule()] });
const walletAddress = await dnsConnect.resolve('test.custom', 'ETH');
console.log(walletAddress);
```

## Integrate using Resolver Smart Contract (CCIP Read)

DNS Connect provides [CCIP Read](https://eips.ethereum.org/EIPS/eip-3668)-compatible Resolver smart contracts to support secure name resolution using standard web3 libraries. CCIP Read will perform an offchain lookup through a Gateway which implements DNS Connect SDK to resolve the name or address.

The following methods are available in the Resolver smart contracts to handle forward and reverse name resolution.

```javascript
/**
 * @notice Resolve a name to an address using CCIP Read
 * @param name Name to resolve.
 * @param network (Optional) Network (blockchain) to resolve the name for. If not provided, defaults to current network.
 * @return resolvedAddress Resolved address.  
 */
function resolve(
        string name,
        string network
) external view returns (address);

/**
 * @notice Reverse resolve an address to a name using CCIP Read
 * @param addr Address to resolve.
 * @param network (Optional) Network (blockchain) to use. If not provided, defaults to current network.
 * @return name Resolved name.
 */
function reverseResolve(
  address addr,
  string network
) external view returns (string)
```

Any client that support CCIP Read can be used to interact with these smart contract methods. For example:

* Blockchain explorers
* Web3 libraries
  * [ethers.js](https://docs.ethers.org/v6/api/providers/#PreparedTransactionRequest-enableCcipRead)
  * [web3.js](https://web3py.readthedocs.io/en/stable/web3.eth.html#web3.eth.Eth.call)

Example resolving a name using ethers.js:

```javascript
// RPC url of a network
const rpcURL = 'https://rpc.example.com';
// D3 Resolver address on a given network (from docs)
const resolverAddress = '0x0123...';
const abi = [
  'function resolve(string name, string network) public view returns (address)',
  'function reverseResolve(address addr, string network) public view returns (string)',
];
const provider = new JsonRpcProvider(rpcURL);
const resolverContract = new ethers.Contract(resolverAddress, abi, provider);

// Resolve a name to address
const address = await resolverContract.resolve(
  'example.shib',
  // If empty, name will be resolved for current blockchain
  '', 
  // Important to explicitly enable CCIP Read
  { enableCcipRead: true }
);
console.log(`Resolved address: ${address}`);

// Reverse resolve an address to name
const name = await resolverContract.reverseResolve(
  '0x03456...',
  '',
  {
    enableCcipRead: true,
  },
);
console.log(`Resolved name: ${name}`);
```

Below is the list of Resolver contract addresses on Mainnet and Testnet

<table><thead><tr><th width="137.33333333333331">Blockchain</th><th width="421">Mainnet Address</th><th>Testnet Address</th></tr></thead><tbody><tr><td>Shibarium</td><td><a href="https://www.shibariumscan.io/address/0xD60D40674E678F0089736D6381071973a75B4B6f">0xD60D40674E678F0089736D6381071973a75B4B6f</a></td><td><a href="https://puppyscan.shib.io/address/0x91c2d22ca1028B2E55e3097096494Eb34b7fc81c">0x91c2d22ca1028B2E55e3097096494Eb34b7fc81c</a></td></tr><tr><td>Core</td><td><a href="https://scan.coredao.org/address/0xe242864ADA335285fAe70Fd752d03AAA1421dC75">0xe242864ADA335285fAe70Fd752d03AAA1421dC75</a></td><td><a href="https://scan.test.btcs.network/address/0x87621Bb14fe30f7F91CAC744eEab8505927A2e9f">0x87621Bb14fe30f7F91CAC744eEab8505927A2e9f</a></td></tr><tr><td>ApeChain</td><td><a href="https://apechain.calderaexplorer.xyz/address/0xeA54b0E40E956383C95e28cb407FF35235Aa31fE">0xeA54b0E40E956383C95e28cb407FF35235Aa31fE</a></td><td><a href="https://curtis.explorer.caldera.xyz/address/0xE3E3478f62C4B3293BadE301400a903a2d879Da3">0xE3E3478f62C4B3293BadE301400a903a2d879Da3</a></td></tr></tbody></table>


# DNS Connect Metamask Snap

The DNS Connect Snap is a MetaMask extension that enables custom name resolution using the D3 DNS Connect SDK. Once installed, you can use any D3 name (e.g. d3connect.core) instead of a wallet address to send/receive crypto in MetaMask.

Visit the [DNS Connect Metamask Snap page](https://snaps.metamask.io/snap/npm/d3-inc/d3connect-snap/) to install the DNS Connect Snap in your Metamask browser extension. (Minimum 12.4.2 version required)

<figure><img src="/files/mTTGACVP9irjk9QmFsTI" alt="" width="356"><figcaption></figcaption></figure>


# Channel Partner Integrations

## Introduction

D3 offers three primary integration methods to suit various levels of development effort and functionality needs. Each option allows developers to seamlessly incorporate D3 features into their applications, ranging from simple affiliate links to full API integrations.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>D3 Network</strong></td><td>The simplest integration option. Redirect users to specific D3 pages for seamless checkout experiences.</td><td><a href="/pages/GfJIpnSH8ihjcWM0juRF">/pages/GfJIpnSH8ihjcWM0juRF</a></td></tr><tr><td></td><td><strong>D3 Embed</strong></td><td>A customizable widget that can be embedded directly into your platform with minimal code. </td><td><a href="/pages/LjZjgRdhcdIleIx5eYw8">/pages/LjZjgRdhcdIleIx5eYw8</a></td></tr><tr><td></td><td><strong>D3 API</strong></td><td>Provides a robust suite of endpoints that allow for a fully custom integration of D3 features directly into your application.</td><td><a href="/pages/wDnZEuRT4sSsg1Yk8DLJ">/pages/wDnZEuRT4sSsg1Yk8DLJ</a></td></tr></tbody></table>


# D3 Link

## D3 Network Overview

The simplest integration option. Redirect users to specific D3 pages for seamless checkout experiences.

**Steps to Implement**:

1. Sign up for the D3 Affiliate Program by contacting <hello@d3.email>.
2. Generate campaign-specific affiliate links.
3. Place these links on your website or app to redirect users to D3’s checkout.

**Example**:

```html
<a href="https://d3.app/search?utm_campaign=yourAffiliateID">Shop Now</a>
```


# D3 Embed

## D3 Embed Overview

A customizable widget that can be embedded directly into your platform with minimal code, D3 Embed will make it easier than ever to integrate Name Token sales into your platform.  D3 Embed is a simple yet powerful tool designed to seamlessly fit into your website or application, allowing your users to interact with D3 services directly from your site.

The widget will enable users to:

* Search for domain names: Let your users browse and discover the perfect domain name in just a few clicks.&#x20;
* Purchase domains: The widget supports purchasing with various crypto currencies/blockchains (fiat coming soon), giving your users flexibility in payment options.&#x20;
* Customization options: Keep your own branding and style by easily customizing the widget’s look and feel to match your site. You can even customize checkout options, making it fit perfectly with your existing payment processes.&#x20;
* Instant integration: No complex coding required. The widget is designed to be plug-and-play, allowing you to embed it easily with just a few lines of code.

Why Integrate the D3 Widget?&#x20;

* Seamless Experience: Keep your users on your site while offering them the full power of D3’s domain services.&#x20;
* Boost Engagement: By embedding the widget, you’ll provide a valuable feature that keeps your users engaged with your platform.&#x20;
* Monetization Opportunities: Incorporate the widget into your monetization strategy, allowing you to offer premium services without heavy development overhead.&#x20;

## Getting Started

* [Demo Widget](https://d3-inc.github.io/marketplace-widget/)
* [Sample Source Code](https://github.com/d3-inc/marketplace-widget/tree/main/packages/widget-test-app) (See our github repository for example integration of the widget)
* Detailed Steps 👇

Sign up at [D3 Developer Dashboard ](https://developers.d3.app)to get your own API keys today.

## 1. Installation

Install the widget package using `npm`, `yarn` or `pnpm.`

{% tabs %}
{% tab title="NPM" %}

```sh
npm install @d3-inc/marketplace-widget
```

{% endtab %}

{% tab title="Yarn" %}

```bash
yarn add @d3-inc/marketplace-widget
```

{% endtab %}
{% endtabs %}

### Peer Dependencies

Make sure the peer dependencies required by the widget are correctly installed in your app.

```javascript
"@tanstack/react-query": "^5.56.2",
"react": "^18.0",
"react-dom": "^18.0",
"zustand": "^4.5.0"
```

### Styles

Import the styles in the root of the app, so these are accessible by the widget.

```javascript
import '@d3-inc/marketplace-widget/styles.css';
```

## 2. Usage

### Scenario 1: Install widget with built-in Connect Wallet implementation

This is the quickest and simplest integration scenario. The D3 widget has complete support for wallet management within the widget, which will handle the wallet connection, chains and transactions management.

The widget uses `wagmi` and `viem` for EVM wallet management. So, if your app already uses the wagmi library, the widget will try to reuse the same config. You can also provide additional props for use in the wagmi config.

The user can connect and disconnect wallet from the widget. The widget doesn't persist the connect wallet, so on page refresh the user needs to re-connect the wallet.

We support the connectors below in the widget.

* [injected](https://wagmi.sh/react/api/connectors/injected)
* [coinbaseWallet](https://wagmi.sh/react/api/connectors/coinbaseWallet)
* [walletConnect](https://wagmi.sh/react/api/connectors/walletConnect)

You can check more details in the [wagmi](https://wagmi.sh/react/api/connectors)[ docs](https://wagmi.sh/react/api/connectors).

Make sure to pass a valid `wallet-connect` developer key in the config, which will be used in the wallet-connect connector. You can get a wallet-connect developer key from [![](https://cloud.reown.com/icon.ico?16ea41eb49a00f1e)Reown Cloud | Sign In](https://cloud.reown.com/sign-in)

```tsx
<D3Widget
  appName="Your app name"
  config={{
    appearance: 'light',  // light | dark | auto
    apiKey: d3ApiKey,  // Get your api key from https://developers.d3.app
    tlds: [],  // One or more TLDs or leave blank to list all available TLDs
    apiEndpoint: 'https://api-public.d3.app',
    walletConfig: {
      walletConnectKey,  // Optional. If provided, widget will use wallet-connect
    },
  }}
/>
```

You can pass some additional props for connect wallet flow

```typescript
walletConfig: {
  walletConnectKey: string;
  walletConnect?: WalletConnectParameters;
  coinbase?: CoinbaseWalletParameters;
  metaMask?: MetaMaskParameters;
}
//Above types are being re-used from the @wagmi/connectors. You can check more details here
```

### Scenario 2: Install widget using callback method

This integration mode of the d3 widget doesn't initialize any internal wallet modules and uses the callback approach to handle the purchase and cart management. This option is helpful in case your dApp already has wallet and blockchain integrations and you don't want to include any additional web3 libs.

To integrate the widget using callback method, you can initialize the widget like below:

```typescript
import { D3Widget } from '@d3-inc/marketplace-widget';

<D3Widget
  appName="Your app name"
  config={{
    appearance: 'light',
    apiKey: d3ApiKey,
    showRecommendations: true,
    // This is important to pass in the initialization, which tells the widget about the integration mode.
    walletAddress: address,
    // callback to handle the crypto transaction on this yourself. Refer to below section to learn more.
    onPurchaseInit: handlePurchaseTransaction,
    tlds: widgetTlds,
    apiEndpoint: 'https://api-public.d3.app',
  }}
/>

// Purchase transaction callback will receive 3 parameters
import type { CheckoutCallback, PaymentOption } from '@d3-inc/marketplace-widget';

type PurchaseTransactionProps = {
  handleOnSuccess: (receipt: TransactionReceipt | undefined) => void;
  handleOnError: (error: BaseError | string) => void;
  transactionVoucher: CheckoutCallback;
};

  async function handleCryptoCheckout({
    transactionVoucher,
    handleOnError,
    handleOnSuccess,
  }: HandleCryptoCheckoutProps) {
    // Your logic related to the crypto transaction goes here
    // Please check the detailed types of CheckoutCallback
  }
```

Below props should be provided to widget for purchase flow

* `walletAddress: (0x${string} | string)`
  * this will be used for the purchase transaction
  * make sure to keep it updated in the host app, so only the currently connected wallet is used for purchase transaction.
* `onPurchaseInit:`callback with below parameters

```typescript
onPurchaseInit: ({
  transactionVoucher,
  handleOnError,
  handleOnSuccess
}) => Promise<void>

// the widget exports the types for these arguments 
import type { CheckoutCallback, PaymentOption } from '@d3-inc/marketplace-widget';

// than you can use these types in the callback (if your project uses typescript)
// below is the detailed overview of the transactionVoucher parameter

type PaymentOption = {
  tokenAddress: string;
  contractAddress: string;
  symbol: string;
  icon: string;
  price: number;
  addressType: WalletAddress;
  chainId: string; // this is important to check the chain, where this payment option is available on
};

type CheckoutOrderRequestResponse = {
  voucher: {
    paymentId: string;
    amount: string;
    token: `0x${string}` | string;
    buyer: `0x${string}` | string;
    voucherExpiration: number;
    orderId: string;
    names: {
      label: string;
      tld: string;
      registry: `0x${string}` | string;
      expirationTime: number;
      owner: `0x${string}` | string;
      renewal: false;
    }[];
  };
  signature: `0x${string}` | string;
};

type CheckoutCallback = CheckoutOrderRequestResponse & {
  selectedPaymentToken: PaymentOption;
};

```

{% hint style="info" %}
Since the widget relies on the host app to determine the transaction response, please make sure to properly include the `handleOnSuccess` and `handleOnError` relevant states. Otherwise, the widget might not be able to show any success or error.
{% endhint %}

{% hint style="info" %}
In the callback, `chainId` is also returned in the `paymentOption`. Please make sure to verify the user is on the same chain before proceeding with the transaction to avoid any unexpected failures and issues in the transaction.
{% endhint %}

You can find a complete example of callback approach (with `wagmi` and `viem`) in the examples folder (link will be added).

### Widget API

* `apiKey (string)`
  * You can get the `apikey` from the [D3 Developers Dashboard](https://developers.d3.app) . Make sure to set the correct permissions for this key.
* `tlds (string | string[])`
  * required
  * if you want to use multiple supported `tlds` in the widget, you can pass an array. Make sure to set the permissions correctly in the dashboard for the widget to use multiple `tlds`. See [here](#supported-tlds) for full list of supported `tlds`.
* `appName (string)`
  * `optional`
  * This is helpful to show in the wallet transactions, when the widget is used alongside the connect wallet
* `appearance (auto | dark | light)`
  * `optional`
  * defaults to `auto`
  * if `auto`, this will use the system’s theme
  * if `light`, the widget will be shown in light theme
  * if `dark`, the widget will use the dark theme for the UI
* `apiEndpoint (string)`
  * `optional`
  * defaults to `https://api-public.d3.app`
* `showRecommendations (boolean)`
  * `optional`
  * defaults to `false`
  * if `true`, the widget will also show the `AI Recommendations`based on the user’s search input. These are AI generated suggestions and at most 20 results will be shown in the widget.
* `walletAddress: (0x${string} | string)`
  * `required (when callback approach is used)`
  * this will be used for the purchase transaction
  * make sure to keep it updated in the host app, so only the currently connected wallet is used for purchase transaction.
* `onPurchaseInit:`callback with below parameters:

```typescript
onPurchaseInit: ({
  transactionVoucher,
  handleOnError,
  handleOnSuccess
}) => Promise<void>

// the widget exports the types for these arguments 
import type { CheckoutCallback, PaymentOption } from '@d3-inc/marketplace-widget';

// than you can use these types in the callback (if your project uses typescript)
// below is the detailed overview of the transactionVoucher parameter

type PaymentOption = {
  tokenAddress: string;
  contractAddress: string;
  symbol: string;
  icon: string;
  price: number;
  addressType: WalletAddress;
  chainId: string; // this is important to check the chain, where this payment option is available on
};

type CheckoutOrderRequestResponse = {
  voucher: {
    paymentId: string;
    amount: string;
    token: `0x${string}` | string;
    buyer: `0x${string}` | string;
    voucherExpiration: number;
    orderId: string;
    names: {
      label: string;
      tld: string;
      registry: `0x${string}` | string;
      expirationTime: number;
      owner: `0x${string}` | string;
      renewal: false;
    }[];
  };
  signature: `0x${string}` | string;
};

type CheckoutCallback = CheckoutOrderRequestResponse & {
  selectedPaymentToken: PaymentOption;
};

```

### Supported TLDs

<table><thead><tr><th width="206">TLD</th><th>Blockchain</th></tr></thead><tbody><tr><td>shib</td><td>Shibarium</td></tr><tr><td>core</td><td>Core</td></tr><tr><td>vic</td><td>Viction</td></tr><tr><td>ape</td><td>ApeChain</td></tr></tbody></table>


# D3 API

## D3 API Overview

D3 API allow for a fully custom integration of D3 features directly into your application. The API exposes an interface for interacting with Web3 Name Tokens on the D3 registry and allows searching, purchasing and minting, and more.

## Getting Started

* [Demo App](https://d3-inc.github.io/d3-api-demo/)
* [Sample Source Code](https://github.com/d3-inc/d3-api-demo) (See our github repository for an example app built using our APIs)
* Detailed Steps 👇

Sign up at [D3 Developer Dashboard ](https://developers.d3.app)to get your own API keys today.

Swagger for these APIs can also be viewed at <https://api-public.d3.app/swagger#/>&#x20;

## Search name tokens returning availability and pricing

> Provides search, combining availability information and pricing, both in native token and USD.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"SearchPaginatedResponse":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items."},"pageItems":{"description":"List of search items.","type":"array","items":{"$ref":"#/components/schemas/SearchItemResponse"}}},"required":["total","pageItems"]},"SearchItemResponse":{"type":"object","properties":{"sld":{"type":"string","description":"Second-level domain (SLD) of a name token."},"tld":{"type":"string","description":"Top-level domain (TLD) of a name token."},"status":{"type":"string","description":"Name availability status.","enum":["available","registered","reserved"]},"eoi":{"type":"boolean","description":"Indicates whether the name is an EOI name or ICANN domain."},"isListed":{"type":"boolean","description":"When status is registered, indicates if there's an active listing for it."},"registrationExpiresAt":{"type":"string","description":"When name is registered, indicates registration expiration date. Past expiration date means that the name has expired, but in a grace period now. It could be renewed by the current owner, or be back on the market after a grace period has passed.","format":"date-time","nullable":true},"reservationExpiresAt":{"type":"string","description":"When name is reserved, indicates reservation expiration date. When name is available, indicates reservation expiration date for the reserved user.","format":"date-time","nullable":true},"usdPrice":{"type":"string","description":"Price in USD (Deprecated, use registryUsdPrice instead)","nullable":true,"deprecated":true},"registryUsdPrice":{"type":"string","description":"Price in USD","nullable":true},"nativeAmount":{"type":"string","description":"Price in native token (Deprecated, use registryNativePrice instead)","nullable":true,"deprecated":true},"registryNativePrice":{"type":"string","description":"Price in native token","nullable":true},"listNativePrice":{"type":"string","description":"Price in native token for active listing","nullable":true},"listUsdPrice":{"type":"string","description":"Price in USD for active listing","nullable":true},"nativeCurrency":{"type":"object","description":"Native blockchain currency. Will be null if tokenization is unsupported for given TLD"},"clickUrl":{"type":"string","description":"Click URL for more information"},"lockExpiresAt":{"type":"string","description":"When name is locked, indicates lock expiration date. This is the date until which the domain remains locked, after which it may become available.","format":"date-time","nullable":true}},"required":["sld","tld","status","eoi","isListed","registrationExpiresAt","reservationExpiresAt","usdPrice","registryUsdPrice","nativeAmount","registryNativePrice","listNativePrice","listUsdPrice","nativeCurrency","clickUrl","lockExpiresAt"]}}},"paths":{"/v1/partner/search":{"get":{"description":"Provides search, combining availability information and pricing, both in native token and USD.","operationId":"PartnerController_search","parameters":[{"name":"limit","required":false,"in":"query","description":"Number of records to return for pagination.","schema":{"minimum":1,"maximum":100,"default":25}},{"name":"skip","required":false,"in":"query","description":"Number of records to skip for pagination.","schema":{"default":0,"minimum":0}},{"name":"tld","required":false,"in":"query","description":"Top-level domain (TLD) of the name token to search for (comma separated list). Leave empty to search all available TLDs.","schema":{"type":"string"}},{"name":"sld","required":true,"in":"query","description":"Second-level domain (SLD) of the name token to search for (comma separated list)","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchPaginatedResponse"}}}},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing SEARCH permission."}},"summary":"Search name tokens returning availability and pricing","tags":["Partner API"]}}}}
```

## Get name recommendations

> Returns name recommendations based on the provided SLDs and TLDs

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"SearchItemResponse":{"type":"object","properties":{"sld":{"type":"string","description":"Second-level domain (SLD) of a name token."},"tld":{"type":"string","description":"Top-level domain (TLD) of a name token."},"status":{"type":"string","description":"Name availability status.","enum":["available","registered","reserved"]},"eoi":{"type":"boolean","description":"Indicates whether the name is an EOI name or ICANN domain."},"isListed":{"type":"boolean","description":"When status is registered, indicates if there's an active listing for it."},"registrationExpiresAt":{"type":"string","description":"When name is registered, indicates registration expiration date. Past expiration date means that the name has expired, but in a grace period now. It could be renewed by the current owner, or be back on the market after a grace period has passed.","format":"date-time","nullable":true},"reservationExpiresAt":{"type":"string","description":"When name is reserved, indicates reservation expiration date. When name is available, indicates reservation expiration date for the reserved user.","format":"date-time","nullable":true},"usdPrice":{"type":"string","description":"Price in USD (Deprecated, use registryUsdPrice instead)","nullable":true,"deprecated":true},"registryUsdPrice":{"type":"string","description":"Price in USD","nullable":true},"nativeAmount":{"type":"string","description":"Price in native token (Deprecated, use registryNativePrice instead)","nullable":true,"deprecated":true},"registryNativePrice":{"type":"string","description":"Price in native token","nullable":true},"listNativePrice":{"type":"string","description":"Price in native token for active listing","nullable":true},"listUsdPrice":{"type":"string","description":"Price in USD for active listing","nullable":true},"nativeCurrency":{"type":"object","description":"Native blockchain currency. Will be null if tokenization is unsupported for given TLD"},"clickUrl":{"type":"string","description":"Click URL for more information"},"lockExpiresAt":{"type":"string","description":"When name is locked, indicates lock expiration date. This is the date until which the domain remains locked, after which it may become available.","format":"date-time","nullable":true}},"required":["sld","tld","status","eoi","isListed","registrationExpiresAt","reservationExpiresAt","usdPrice","registryUsdPrice","nativeAmount","registryNativePrice","listNativePrice","listUsdPrice","nativeCurrency","clickUrl","lockExpiresAt"]}}},"paths":{"/v1/partner/recommendations":{"get":{"description":"Returns name recommendations based on the provided SLDs and TLDs","operationId":"PartnerController_getRecommendations","parameters":[{"name":"tld","required":false,"in":"query","description":"Top-level domain (TLD) of the name token to recommend (comma separated list). Leave empty to recommend all available TLDs.","schema":{"type":"string"}},{"name":"sld","required":true,"in":"query","description":"Second-level domain (SLD) of the name token to recommend (comma separated list). Maximum of 5 SLDs allowed.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful name recommendations","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SearchItemResponse"}}}}},"400":{"description":"Invalid TLDs or other request issues"},"403":{"description":"Forbidden. API Key is missing necessary permissions."}},"summary":"Get name recommendations","tags":["Partner API"]}}}}
```

## Mint a name token

> Accepts mint name request. Only allows minting of non-premium name tokens (requires NON\_PREMIUM\_MINT permission).Token is not minted immediately but is scheduled for minting. Mint status could be checked using token status endpoint.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"PartnerMintRequest":{"type":"object","properties":{"sld":{"type":"string","description":"Second-level domain (SLD) of the name to mint."},"tld":{"type":"string","description":"Top-level domain (TLD) of the name to mint."},"user":{"description":"User information required to mint the name.","allOf":[{"$ref":"#/components/schemas/PartnerUserRequest"}]}},"required":["sld","tld","user"]},"PartnerUserRequest":{"type":"object","properties":{"wallet":{"type":"string","description":"Wallet address to mint the name for. Format is chain-specific, and depends on a chosen TLD."},"email":{"type":"object","description":"Users email address. Used for renewal notifications and support.","format":"email"}},"required":["wallet"]},"PartnerMintResponse":{"type":"object","properties":{"tokenId":{"type":"string","description":"Token ID that will be minted."},"contractAddress":{"type":"string","description":"NFT Smart Contract address, which will be used to mint the token."},"chainId":{"type":"string","description":"Chain ID of the blockchain network where the token will be minted. For EVM chains, Chain ID is returned."}},"required":["tokenId","contractAddress","chainId"]}}},"paths":{"/v1/partner/mint":{"post":{"description":"Accepts mint name request. Only allows minting of non-premium name tokens (requires NON_PREMIUM_MINT permission).Token is not minted immediately but is scheduled for minting. Mint status could be checked using token status endpoint.","operationId":"PartnerController_partnerMint","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerMintRequest"}}}},"responses":{"202":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerMintResponse"}}}},"400":{"description":"Bad Request. Unable to mint the requested name token."},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing NON_PREMIUM_MINT permission."},"409":{"description":"Conflict. Name token is already minted."}},"summary":"Mint a name token","tags":["Partner API"]}}}}
```

## Get supported payment methods for name tokens

> Returns the supported payment options (contract and token addresses) for the provided TLDs.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"PaymentOptionsResponse":{"type":"object","properties":{"options":{"description":"Array of payment options, each containing contract and token addresses","type":"array","items":{"$ref":"#/components/schemas/PaymentOptionResponse"}}},"required":["options"]},"PaymentOptionResponse":{"type":"object","properties":{"chainId":{"type":"string","description":"Chain ID of the blockchain network where the contract is deployed."},"chainName":{"type":"string","description":"Name of the blockchain network where the contract is deployed."},"addressType":{"type":"string","description":"Wallet address type for the current chain.","enum":["EVM","SUI","NEAR","TOKENPROOF","SOLANA"]},"contractAddress":{"type":"string","description":"The contract address of the payment method"},"tokenAddress":{"type":"object","description":"The token address used in the payment method"},"symbol":{"type":"object","description":"The token symbol used in the payment method currency"},"icon":{"type":"object","description":"The token icon used in the payment method currency"},"price":{"type":"number","description":"The token price used in the payment method"}},"required":["chainId","chainName","addressType","contractAddress","tokenAddress","symbol","icon","price"]}}},"paths":{"/v1/partner/payment/options":{"get":{"description":"Returns the supported payment options (contract and token addresses) for the provided TLDs.","operationId":"PartnerController_getPaymentOptions","parameters":[{"name":"tld","required":false,"in":"query","description":"Top-level domain (TLD) of the name token to fetch payment options (comma separated list). Leave empty to fetch for all available TLDs.","schema":{"type":"string"}}],"responses":{"200":{"description":"Returns payment options for name tokens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentOptionsResponse"}}}},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing PURCHASE permission."}},"summary":"Get supported payment methods for name tokens","tags":["Partner API"]}}}}
```

## Create a partner order for name token purchase

> Creates a new order for name token purchase. The response includes a payment voucher and details necessary to complete the purchase.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"PartnerOrderRequest":{"type":"object","properties":{"paymentOptions":{"description":"The payment options for the transaction","allOf":[{"$ref":"#/components/schemas/OrderPaymentOptionsRequest"}]},"names":{"description":"Array of names to mint, each including an SLD and TLD","type":"array","items":{"$ref":"#/components/schemas/NameRequest"}},"registrantContact":{"description":"The registrant contact for ICANN TLDs","allOf":[{"$ref":"#/components/schemas/ContactRequestModel"}]}},"required":["paymentOptions","names"]},"OrderPaymentOptionsRequest":{"type":"object","properties":{"contractAddress":{"type":"string","description":"The contract address of the payment method"},"tokenAddress":{"type":"string","description":"The token address used in the payment method"},"buyerAddress":{"type":"string","description":"The address of the buyer"}},"required":["contractAddress","tokenAddress","buyerAddress"]},"NameRequest":{"type":"object","properties":{"sld":{"type":"string","description":"Second-level domain (SLD) of the name to mint"},"tld":{"type":"string","description":"Top-level domain (TLD) of the name to mint"},"autoRenew":{"type":"boolean","description":"Whether to auto-renew the domain after it expires","default":true},"domainLength":{"type":"number","description":"The length of the domain registration in years","enum":[1,2,3,4,5,6,8,10],"default":1}},"required":["sld","tld"]},"ContactRequestModel":{"type":"object","properties":{"firstName":{"type":"string","description":"First name of the registrant"},"lastName":{"type":"string","description":"Last name of the registrant"},"organization":{"type":"object","description":"Organization name"},"email":{"type":"string","description":"Email address","format":"email"},"phone":{"type":"string","description":"Phone number"},"phoneCountryCode":{"type":"string","description":"Phone country code"},"fax":{"type":"object","description":"Fax number"},"faxCountryCode":{"type":"object","description":"Fax country code"},"street":{"type":"string","description":"Street address"},"city":{"type":"string","description":"City"},"state":{"type":"string","description":"State/Province"},"postalCode":{"type":"string","description":"Postal code"},"countryCode":{"type":"string","description":"Country code (ISO 3166-1 alpha-2)"}},"required":["firstName","lastName","email","phone","phoneCountryCode","street","city","state","postalCode","countryCode"]},"PartnerOrderResponse":{"type":"object","properties":{"voucher":{"description":"The voucher details including names, amount, and expiration","oneOf":[{"type":"object","properties":{"buyer":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string"},"voucherExpiration":{"type":"number"},"paymentId":{"type":"string"},"orderId":{"type":"string"},"names":{"type":"array","items":{"type":"object","properties":{"registry":{"type":"string"},"label":{"type":"string"},"tld":{"type":"string"},"expirationTime":{"type":"number"},"owner":{"type":"string"},"renewal":{"type":"boolean"}}}}}},{"type":"object","properties":{"buyer":{"type":"string"},"token":{"type":"string","nullable":true},"amount":{"type":"string"},"voucher_expiration":{"type":"number"},"payment_id":{"type":"string"},"order_id":{"type":"string"},"registry":{"type":"string"},"names":{"type":"array","items":{"type":"object","properties":{"sld":{"type":"string"},"tld":{"type":"string"},"expiration_time":{"type":"string"},"owner":{"type":"string"},"token_metadata":{"type":"object","properties":{"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"media":{"type":"string","nullable":true},"media_hash":{"type":"string","nullable":true},"copies":{"type":"number","nullable":true},"issued_at":{"type":"string","nullable":true},"expires_at":{"type":"string","nullable":true},"starts_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"reference":{"type":"string","nullable":true},"reference_hash":{"type":"string","nullable":true},"extra":{"type":"string","nullable":true}}},"account_public_key":{"type":"string","nullable":true}}}}}}]},"signature":{"type":"string","description":"The signature of the voucher for submission"}},"required":["voucher","signature"]}}},"paths":{"/v1/partner/order":{"post":{"description":"Creates a new order for name token purchase. The response includes a payment voucher and details necessary to complete the purchase.","operationId":"PartnerController_createPartnerOrder","parameters":[],"requestBody":{"required":true,"description":"Details required to create an order for name token purchase","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderRequest"}}}},"responses":{"201":{"description":"The order has been successfully created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderResponse"}}}},"400":{"description":"Bad Request. Some names are not available for purchase."},"403":{"description":"Forbidden. API Key is missing necessary permissions."}},"summary":"Create a partner order for name token purchase","tags":["Partner API"]}}}}
```

## Get name token metadata

> Returns metadata and registration status of a name token.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"TokenStatusResponse":{"type":"object","properties":{"status":{"type":"string","description":"Status of the name token.","enum":["pending","waiting_for_finalization","registered"]},"sld":{"type":"string","description":"Second-level domain (SLD) of a name token. Only present when name token is registered."},"tld":{"type":"string","description":"Top-level domain (TLD) of a name token. Only present when name token is registered."},"registeredAt":{"format":"date-time","type":"string","description":"Domain registration date. Only present when name token is registered."},"expirationDate":{"format":"date-time","type":"string","description":"Expiration date of a registered name token. May return a past date if the token has expired. Only present when name token is registered."},"owner":{"type":"string","description":"Owner wallet address. Format is chain-specific. Only present when name token is registered."},"tokenId":{"type":"string","description":"Minted Token ID. Only present when name token is registered."},"contractAddress":{"type":"string","description":"NFT Smart Contract address. Only present when name token is registered."},"chainId":{"type":"string","description":"Chain ID of the blockchain network. Only present when name token is registered or waiting for finalization."},"txHash":{"type":"string","description":"Mint transaction hash. Only present when name token is waiting for finalization."},"imageURL":{"type":"string","description":"Token image URL, only present if token is minted."}},"required":["status"]}}},"paths":{"/v1/partner/token/{sld}/{tld}":{"get":{"description":"Returns metadata and registration status of a name token.","operationId":"PartnerController_tokenStatus","parameters":[{"name":"tld","required":true,"in":"path","description":"Top-level domain (TLD) of the name token.","schema":{}},{"name":"sld","required":true,"in":"path","description":"Second-level domain (SLD) of the name token.","schema":{}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenStatusResponse"}}}},"400":{"description":"Bad Request. Wrong SLD or TLD format."},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing NON_PREMIUM_MINT permission."},"404":{"description":"Not Found. Name token is not registered and mint is not in progress."}},"summary":"Get name token metadata","tags":["Partner API"]}}}}
```

## Get name token metadata by token ID

> Returns metadata of a name token by token ID.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"TokenStatusResponse":{"type":"object","properties":{"status":{"type":"string","description":"Status of the name token.","enum":["pending","waiting_for_finalization","registered"]},"sld":{"type":"string","description":"Second-level domain (SLD) of a name token. Only present when name token is registered."},"tld":{"type":"string","description":"Top-level domain (TLD) of a name token. Only present when name token is registered."},"registeredAt":{"format":"date-time","type":"string","description":"Domain registration date. Only present when name token is registered."},"expirationDate":{"format":"date-time","type":"string","description":"Expiration date of a registered name token. May return a past date if the token has expired. Only present when name token is registered."},"owner":{"type":"string","description":"Owner wallet address. Format is chain-specific. Only present when name token is registered."},"tokenId":{"type":"string","description":"Minted Token ID. Only present when name token is registered."},"contractAddress":{"type":"string","description":"NFT Smart Contract address. Only present when name token is registered."},"chainId":{"type":"string","description":"Chain ID of the blockchain network. Only present when name token is registered or waiting for finalization."},"txHash":{"type":"string","description":"Mint transaction hash. Only present when name token is waiting for finalization."},"imageURL":{"type":"string","description":"Token image URL, only present if token is minted."}},"required":["status"]}}},"paths":{"/v1/partner/token/{chainId}/{contractAddress}/{tokenId}":{"get":{"description":"Returns metadata of a name token by token ID.","operationId":"PartnerController_getTokenById","parameters":[{"name":"chainId","required":true,"in":"path","description":"Chain ID of the blockchain network.","schema":{"type":"string"}},{"name":"contractAddress","required":true,"in":"path","description":"NFT Smart Contract address.","schema":{"type":"string"}},{"name":"tokenId","required":true,"in":"path","description":"Minted Token ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenStatusResponse"}}}},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing SEARCH permission."},"404":{"description":"Not Found. Name token does not exist for this contract on this chain or contract not found."}},"summary":"Get name token metadata by token ID","tags":["Partner API"]}}}}
```

## Get name token metadata by multiple token IDs at once

> Returns metadata of multiple name tokens by their token IDs.

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"BulkTokenStatusRequest":{"type":"object","properties":{"tokenIds":{"description":"List of token ids to lookup for","type":"array","items":{"type":"string"}}},"required":["tokenIds"]},"TokenStatusResponse":{"type":"object","properties":{"status":{"type":"string","description":"Status of the name token.","enum":["pending","waiting_for_finalization","registered"]},"sld":{"type":"string","description":"Second-level domain (SLD) of a name token. Only present when name token is registered."},"tld":{"type":"string","description":"Top-level domain (TLD) of a name token. Only present when name token is registered."},"registeredAt":{"format":"date-time","type":"string","description":"Domain registration date. Only present when name token is registered."},"expirationDate":{"format":"date-time","type":"string","description":"Expiration date of a registered name token. May return a past date if the token has expired. Only present when name token is registered."},"owner":{"type":"string","description":"Owner wallet address. Format is chain-specific. Only present when name token is registered."},"tokenId":{"type":"string","description":"Minted Token ID. Only present when name token is registered."},"contractAddress":{"type":"string","description":"NFT Smart Contract address. Only present when name token is registered."},"chainId":{"type":"string","description":"Chain ID of the blockchain network. Only present when name token is registered or waiting for finalization."},"txHash":{"type":"string","description":"Mint transaction hash. Only present when name token is waiting for finalization."},"imageURL":{"type":"string","description":"Token image URL, only present if token is minted."}},"required":["status"]}}},"paths":{"/v1/partner/tokens/{chainId}/{contractAddress}":{"post":{"description":"Returns metadata of multiple name tokens by their token IDs.","operationId":"PartnerController_getBatchedTokenById","parameters":[{"name":"chainId","required":true,"in":"path","description":"Chain ID of the blockchain network.","schema":{"type":"string"}},{"name":"contractAddress","required":true,"in":"path","description":"NFT Smart Contract address.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkTokenStatusRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TokenStatusResponse"}}}}},"400":{"description":"Bad Request. Wrong address or address type format."},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing SEARCH permission."},"404":{"description":"Not Found. Chain or Contract not found."}},"summary":"Get name token metadata by multiple token IDs at once","tags":["Partner API"]}}}}
```

## Get name tokens for a wallet address

> Returns registered name tokens for a wallet address

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"PaginatedTokensResponse":{"type":"object","properties":{"total":{"type":"number","description":"Total number of name tokens."},"pageItems":{"description":"List of name tokens.","type":"array","items":{"$ref":"#/components/schemas/TokenInfoResponse"}}},"required":["total","pageItems"]},"TokenInfoResponse":{"type":"object","properties":{"sld":{"type":"string","description":"Second-level domain (SLD) of a name token."},"tld":{"type":"string","description":"Top-level domain (TLD) of a name token."},"registeredAt":{"format":"date-time","type":"string","description":"Domain registration date. Only present when name token is registered."},"expirationDate":{"format":"date-time","type":"string","description":"Expiration date of a name token. May return a past date if the token has expired."},"tokenId":{"type":"string","description":"Token ID."},"contractAddress":{"type":"string","description":"NFT Smart Contract address."},"chainId":{"type":"string","description":"Chain ID of the blockchain network. Only present when name token is registered or waiting for finalization."}},"required":["sld","tld"]}}},"paths":{"/v1/partner/tokens/{addressType}/{address}":{"get":{"description":"Returns registered name tokens for a wallet address","operationId":"PartnerController_walletTokens","parameters":[{"name":"limit","required":false,"in":"query","description":"Number of records to return for pagination.","schema":{"minimum":1,"maximum":100,"default":25}},{"name":"skip","required":false,"in":"query","description":"Number of records to skip for pagination.","schema":{"default":0,"minimum":0}},{"name":"address","required":true,"in":"path","description":"Wallet address.","schema":{}},{"name":"addressType","required":true,"in":"path","description":"Wallet address type.","schema":{"enum":["EVM","SUI","NEAR","TOKENPROOF","SOLANA"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedTokensResponse"}}}},"400":{"description":"Bad Request. Wrong address or address type format."},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing SEARCH permission."}},"summary":"Get name tokens for a wallet address","tags":["Partner API"]}}}}
```

## POST /v1/domain/{domainName}/records/web3

>

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"SetWeb3RecordBody":{"type":"object","properties":{"symbol":{"type":"string","description":"The symbol representing the asset or record, typically used as a short identifier (e.g., \"BTC\" for Bitcoin)."},"address":{"type":"string","description":"The address to associate with the domain and symbol. This is typically a blockchain address."},"signature":{"type":"string","description":"The signature generated by the registrant's wallet, authorizing this operation."},"signatureExpiresAt":{"type":"number","description":"The UNIX timestamp (in milliseconds) when the signature expires."}},"required":["symbol","address","signature","signatureExpiresAt"]}}},"paths":{"/v1/domain/{domainName}/records/web3":{"post":{"operationId":"Web3RecordsController_setWeb3Record","parameters":[{"name":"domainName","required":true,"in":"path","description":"The domain name to set the web3 record for","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetWeb3RecordBody"}}}},"responses":{"400":{"description":"Bad Request. Signature has expired or invalid."},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing WALLET_MAPPING permission."},"404":{"description":"Not Found. Domain does not exist."}},"tags":["Wallet Mapping API"]}}}}
```

## DELETE /v1/domain/{domainName}/records/web3

>

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"DeleteWeb3RecordBody":{"type":"object","properties":{"symbol":{"type":"string","description":"The symbol representing the asset or record, typically used as a short identifier (e.g., \"BTC\" for Bitcoin)."},"signature":{"type":"string","description":"The signature generated by the registrant's wallet, authorizing this operation."},"signatureExpiresAt":{"type":"number","description":"The UNIX timestamp (in milliseconds) when the signature expires."}},"required":["symbol","signature","signatureExpiresAt"]}}},"paths":{"/v1/domain/{domainName}/records/web3":{"delete":{"operationId":"Web3RecordsController_deleteWeb3Record","parameters":[{"name":"domainName","required":true,"in":"path","description":"The domain name to delete the web3 record from","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteWeb3RecordBody"}}}},"responses":{"400":{"description":"Bad Request. Signature has expired or invalid."},"401":{"description":"Unauthorized. API Key is missing or invalid."},"403":{"description":"Forbidden. API Key is missing WALLET_MAPPING permission."},"404":{"description":"Not Found. Domain does not exist."}},"tags":["Wallet Mapping API"]}}}}
```

## POST /v1/reverse-registry/{wallet}

>

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"SetPrimaryNameBody":{"type":"object","properties":{"name":{"type":"string","description":"The name to set as the primary name for the wallet"},"signature":{"type":"string","description":"The signature to verify the request"},"signatureExpiresAt":{"type":"number","description":"The timestamp when the signature expires"}},"required":["name","signature","signatureExpiresAt"]}}},"paths":{"/v1/reverse-registry/{wallet}":{"post":{"operationId":"ReverseRegistryController_setPrimaryName","parameters":[{"name":"wallet","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPrimaryNameBody"}}}},"responses":{"200":{"description":""}},"tags":["Reverse Wallet Mapping API"]}}}}
```

## DELETE /v1/reverse-registry/{wallet}

>

```json
{"openapi":"3.0.0","info":{"title":"D3 External API","version":"1.0"},"security":[{"Api-Key":[]}],"components":{"securitySchemes":{"Api-Key":{"type":"apiKey","in":"header","name":"Api-Key"}},"schemas":{"UnsetPrimaryNameBody":{"type":"object","properties":{"signature":{"type":"string","description":"The signature to verify the request"},"signatureExpiresAt":{"type":"number","description":"The timestamp when the signature expires"}},"required":["signature","signatureExpiresAt"]}}},"paths":{"/v1/reverse-registry/{wallet}":{"delete":{"operationId":"ReverseRegistryController_unsetPrimaryName","parameters":[{"name":"wallet","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsetPrimaryNameBody"}}}},"responses":{"200":{"description":""}},"tags":["Reverse Wallet Mapping API"]}}}}
```


# Signing requests for wallet mapping API

### Introduction

The Wallet Mapping API allows users to associate blockchain wallet addresses with domain names. This document explains how to properly sign requests for various operations in the API.

### Authentication

All API requests require:

* An API key provided in the header as 'api-key'
* A valid EIP-712 signature for the operation being performed

### API Endpoints

#### 1. Set Wallet Mapping

Associates a blockchain wallet address with a domain for a specific chain/symbol.

```jsx
// Function to set a wallet mapping
async function setWalletMapping(symbol, name) {
  const payload = {
    domain: name,
    symbol,
    address: wallet.address,
    signatureExpiresAt: Date.now() + 5 * 60 * 1000, // 5 minutes
  };
  
  const signature = await wallet.signTypedData(
    SignDomain, 
    SetWeb3RecordTypes, 
    payload
  );
  
  return fetch(`https://api-public.d3.app/v1/domain/${name}/records/web3`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'api-key': API_KEY,
    },
    body: JSON.stringify({
      symbol,
      address: wallet.address,
      signature,
      signatureExpiresAt: payload.signatureExpiresAt,
    }),
  });
}

```

The `SignDomain` and `SetWeb3RecordTypes` constants are defined as:

```jsx
const SignDomain = {
  name: 'D3 API',
  version: '1',
};

const SetWeb3RecordTypes = {
  SetWeb3Record: [
    { name: 'domain', type: 'string' },
    { name: 'symbol', type: 'string' },
    { name: 'address', type: 'string' },
    { name: 'signatureExpiresAt', type: 'uint256' },
  ],
};

```

#### Example

```jsx
// Set "ETH" wallet mapping for domain "example.com"
const response = await setWalletMapping("ETH", "example.d3");
console.log(await response.json());
// Example response: { success: true }

```

#### 2. Delete Wallet Mapping

Removes the association between a wallet address and a domain for a specific chain/symbol.

```jsx
async function deleteWalletMapping(symbol, name) {
  const payload = {
    domain: name,
    symbol,
    signatureExpiresAt: Date.now() + 5 * 60 * 1000, // 5 minutes
  };
  
  const signature = await wallet.signTypedData(
    SignDomain, 
    DeleteWeb3RecordTypes, 
    payload
  );
  
  return fetch(`https://api-public.d3.app/v1/domain/${name}/records/web3`, {
    method: 'DELETE',
    headers: {
      'Content-Type': 'application/json',
      'api-key': API_KEY,
    },
    body: JSON.stringify({
      symbol,
      signature,
      signatureExpiresAt: payload.signatureExpiresAt,
    }),
  });
}

```

The `DeleteWeb3RecordTypes` constant is defined as:

```jsx
const DeleteWeb3RecordTypes = {
  DeleteWeb3Record: [
    { name: 'domain', type: 'string' },
    { name: 'symbol', type: 'string' },
    { name: 'signatureExpiresAt', type: 'uint256' },
  ],
};

```

#### Example

```jsx
// Delete "ETH" wallet mapping for domain "example.com"
const response = await deleteWalletMapping("ETH", "example.com");
console.log(await response.json());
// Example response: { success: true }

```

#### 3. Set Primary Name

Sets a domain as the primary name for a wallet address (reverse resolution).

```jsx
async function setPrimaryName(wallet, name) {
  const payload = {
    name,
    signatureExpiresAt: Date.now() + 5 * 60 * 1000, // 5 minutes
  };
  
  const signature = await wallet.signTypedData(
    SignDomain, 
    SetPrimaryNameTypes, 
    payload
  );
  
  return fetch(`https://api-public.d3.app/v1/reverse-registry/${wallet.address}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'api-key': API_KEY,
    },
    body: JSON.stringify({
      name,
      signature,
      signatureExpiresAt: payload.signatureExpiresAt,
    }),
  });
}

```

The `SetPrimaryNameTypes` constant is defined as:

```jsx
const SetPrimaryNameTypes = {
  SetPrimaryName: [
    { name: 'name', type: 'string' },
    { name: 'signatureExpiresAt', type: 'uint256' },
  ],
};

```

#### Example

```jsx
// Set "example.com" as the primary name for the wallet
const response = await setPrimaryName(wallet, "example.com");
console.log(await response.json());
// Example response: { success: true }

```

#### 4. Unset Primary Name

Removes the primary name association for a wallet address.

```jsx
async function unsetPrimaryName(wallet) {
  const payload = {
    signatureExpiresAt: Date.now() + 5 * 60 * 1000, // 5 minutes
  };
  
  const signature = await wallet.signTypedData(
    SignDomain, 
    UnsetPrimaryNameTypes, 
    payload
  );
  
  return fetch(`https://api-public.d3.app/v1/reverse-registry/${wallet.address}`, {
    method: 'DELETE',
    headers: {
      'Content-Type': 'application/json',
      'api-key': API_KEY,
    },
    body: JSON.stringify({
      signature,
      signatureExpiresAt: payload.signatureExpiresAt,
    }),
  });
}

```

The `UnsetPrimaryNameTypes` constant is defined as:

```jsx
const UnsetPrimaryNameTypes = {
  UnsetPrimaryName: [
    { name: 'signatureExpiresAt', type: 'uint256' }
  ],
};

```

#### Example

```jsx
// Remove the primary name for the wallet
const response = await unsetPrimaryName(wallet);
console.log(await response.json());
// Example response: { success: true }

```

### Complete Working Example

Here's a complete example that demonstrates all operations:

```jsx
const { ethers } = require('ethers');

// Configuration
const API_KEY = 'your-api-key-here';
const PRIVATE_KEY = 'your-private-key'; // Should be stored securely
const wallet = new ethers.Wallet(PRIVATE_KEY);

// EIP-712 domain
const SignDomain = {
  name: 'D3 API',
  version: '1',
};

// Type definitions for signatures
const SetWeb3RecordTypes = {
  SetWeb3Record: [
    { name: 'domain', type: 'string' },
    { name: 'symbol', type: 'string' },
    { name: 'address', type: 'string' },
    { name: 'signatureExpiresAt', type: 'uint256' },
  ],
};

const DeleteWeb3RecordTypes = {
  DeleteWeb3Record: [
    { name: 'domain', type: 'string' },
    { name: 'symbol', type: 'string' },
    { name: 'signatureExpiresAt', type: 'uint256' },
  ],
};

const SetPrimaryNameTypes = {
  SetPrimaryName: [
    { name: 'name', type: 'string' },
    { name: 'signatureExpiresAt', type: 'uint256' },
  ],
};

const UnsetPrimaryNameTypes = {
  UnsetPrimaryName: [
    { name: 'signatureExpiresAt', type: 'uint256' }
  ],
};

// Example usage
async function demonstrateAllOperations() {
  const domain = "example.com";
  const symbol = "ETH";
  
  // 1. Set wallet mapping
  console.log(`Setting ${symbol} wallet mapping for ${domain}...`);
  const setResponse = await setWalletMapping(symbol, domain);
  console.log(await setResponse.json());
  
  // 2. Set primary name
  console.log(`Setting ${domain} as primary name for wallet...`);
  const setPrimaryResponse = await setPrimaryName(wallet, domain);
  console.log(await setPrimaryResponse.json());
  
  // Wait to demonstrate the operations
  await new Promise(resolve => setTimeout(resolve, 2000));
  
  // 3. Delete wallet mapping
  console.log(`Deleting ${symbol} wallet mapping for ${domain}...`);
  const deleteResponse = await deleteWalletMapping(symbol, domain);
  console.log(await deleteResponse.json());
  
  // 4. Unset primary name
  console.log(`Unsetting primary name for wallet...`);
  const unsetResponse = await unsetPrimaryName(wallet);
  console.log(await unsetResponse.json());
}

// Implementation of API functions
// [Include all the function implementations from above]

// Run the demonstration
demonstrateAllOperations().catch(console.error);

```

### Important Notes

* All signatures expire after the time specified in `signatureExpiresAt` (in milliseconds since epoch)
* The wallet address is derived from the signature, ensuring that only the wallet owner can make changes
* Store your API key and private key securely and never expose them in client-side code
* All endpoints will respond with 200 with an empty body in case of success

### Error Handling

The API returns appropriate HTTP status codes and JSON responses for errors:

* 400 - Bad Request: Invalid parameters or signature
* 401 - Unauthorized: Invalid API key
* 403 - Forbidden: Signature expired or incorrect
* 404 - Not Found: Domain or wallet not found


# Use Cases

Here you can find some common use cases that can be addressed by integrating with D3. Click on one of the sections below to read more.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Sell Name Tokens to Users In your App</td><td></td><td></td><td><a href="/pages/kmAJiZ0KI2WnV7jkLffr">/pages/kmAJiZ0KI2WnV7jkLffr</a></td></tr><tr><td>Send/Receive Crypto to Names in your App </td><td></td><td></td><td><a href="/pages/LtIPy4Ioqo0cl3IHGGaq">/pages/LtIPy4Ioqo0cl3IHGGaq</a></td></tr><tr><td>Reverse Resolve Names in your App</td><td></td><td></td><td><a href="/pages/Da4bR5WSnlthpBtqGZPh">/pages/Da4bR5WSnlthpBtqGZPh</a></td></tr></tbody></table>


# Sell Name Tokens to Users in your App

## Sell Name Tokens to Users in Your App

With D3, you can offer your users the ability to **search for and purchase name tokens** directly within your app. Whether you’re looking for a low-code solution to quickly integrate domain sales or a fully customizable experience, D3 has the tools to make it happen.

## Overview

D3 provides flexible integration options that allow you to sell domains to users seamlessly. Whether you want to quickly add domain purchasing with an [**embeddable widget** ](/channel-partner-integrations/d3-embed)or prefer a more custom solution using [**D3’s robust APIs**](/channel-partner-integrations/d3-api), we’ve got you covered. Your users will be able to search, purchase and mind name tokens all within your app, creating a streamlined experience without needing to leave your platform.

### How to Build This

You have two main options for integrating name token sales into your app, depending on the level of customization you need:

**1.** [**D3 Embed (Low-Code)**](/channel-partner-integrations/d3-embed)

The easiest way to get started. With just a few lines of code, you can integrate D3’s embeddable widget that allows users to search and purchase domains.

* **Quick Setup**: Add a name search and purchase flow to your app without extensive development.
* **Customizable Appearance**: You can align the widget’s look and feel with your app’s branding.

**2.** [**D3 API Integration (Med/High-Code)**](/channel-partner-integrations/d3-api)

For those looking for deeper integration, D3’s **Sales APIs** offer a comprehensive suite of endpoints to fully control the user experience, from searching for domains to purchasing and managing them.

* **Search for Names**:

  <pre class="language-bash"><code class="lang-bash"><strong>GET /v1/partner/search
  </strong></code></pre>
* **Purchase Names:**

  <pre class="language-bash"><code class="lang-bash"><strong>POST /v1/partner/purchase
  </strong></code></pre>
* **Mint Names**:&#x20;

  ```bash
  POST /v1/partner/mint
  ```

#### Example Flow

1. **User Searches for a Name**: The user enters a desired domain name into the search bar in your app, powered by D3’s embeddable widget or API.
2. **Add to cart:** Once a name is selected, the user can add the name to their cart
3. **Name Purchase**:  User can complete the purchase with fiat or crypto, depending on your integration.

## Benefits

* **Increased Revenue**: Offering domain purchasing within your app encourages users to stay on your platform longer and provides an additional revenue stream.
* **Flexible Integration Options**: Choose between a low-code embeddable widget for quick deployment or use the API for more custom control over the domain sales process.
* **Seamless User Experience**: Users can search for, purchase, and manage domains without leaving your app, providing a frictionless experience.

## Why Use D3?

D3’s integration options make it simple to sell domains in your app, whether you’re looking for a quick solution with the embeddable widget or a fully customizable experience with the API. With flexible payment methods, an intuitive user experience, and comprehensive name management, D3 empowers you to deliver valuable services to your users while boosting engagement and revenue.


# Send/Receive Crypto to Names in your App

## Send and Receive Crypto to Names

With D3, you can easily resolve human-readable domain names instead of long, complex wallet addresses. By integrating with [D3 Connect SDK](https://docs.d3.app/), your users can send and receive cryptocurrency seamlessly using their names within your app, making transactions more user-friendly and secure.

#### Overview

[D3’s **name resolution**](/resolve-d3-names) technology enables users to send and receive cryptocurrency using a domain name, rather than traditional wallet addresses. This reduces the risk of errors in sending funds to incorrect addresses. By implementing this functionality in your app, you offer a smoother experience for users and enhance the usability of blockchain payments.

1. **Send Crypto to a Domain Name**: Users can send crypto to a human-readable name (e.g., `johndoe*tld`) instead of needing to copy and paste long wallet addresses.
2. **Receive Crypto via Your Domain**: Allow users to receive payments directly to their names, making it easy to manage multiple cryptocurrencies without needing multiple wallet addresses.
3. **Name Resolution**: D3’s infrastructure automatically resolves the domain name to the associated wallet address, ensuring the correct destination for every transaction.

### How to Build This

You can integrate [**D3 Connect SDK**](/resolve-d3-names) to enable name resolution for cryptocurrency transactions in your app. This SDK allows your users to send and receive crypto by mapping domain names to wallet addresses securely and efficiently.

### Benefits

* **User-Friendly Payments**: Make crypto transactions as easy as sending an email by allowing users to send crypto to simple, memorable domain names.
* **Reduce Errors**: Eliminates the risk of mistakes when copying and pasting long wallet addresses, ensuring transactions go to the correct recipient.
* **Multi-Currency Support**: D3 name resolution supports multiple cryptocurrencies, so users can send or receive different types of crypto to the same domain name.
* **Enhanced Security**: Using D3’s infrastructure, domain name resolution is secured and reliable, giving users confidence in every transaction.

### Why Use D3?

[**D3** **Connect SDK**](/resolve-d3-names) and name resolution infrastructure make it simple to integrate into your app. With fast, secure resolution of domain names into wallet addresses, D3 ensures that your users enjoy a seamless and efficient experience when sending and receiving crypto.


# Reverse Resolve Names in your App

## Reverse Resolution for Names in your App

With [D3’s **Reverse Resolution**](/resolve-d3-names#reverse-wallet-address-resolution), you can map wallet addresses back to identifiable names, making it easier for users to view and manage their identities across blockchain transactions. This capability enhances the user experience by providing human-readable names that correspond to blockchain addresses, improving transparency and simplifying the user journey.

## Overview

D3’s **Reverse Resolution** allows applications to map crypto wallet addresses to their corresponding domain names, enabling users to see a recognizable domain instead of a string of characters. This can be used in transaction histories, user profiles, and across decentralized apps (dApps) to give users a clearer picture of who they're interacting with.

1. **Resolve a Wallet Address to a Domain**: By performing reverse resolution, users can see the associated domain name for a wallet address, instead of the unrecognizable long address.
2. **Unlock Universal Identity**: Show unique, human-friendly names instead of complex wallet addresses user profiles, dApps, transaction logs, helping users easily identify the counterparties they’ve interacted with. This makes decentralized identities more meaningful and accessible.

## Benefits

D3 Connect SDK offers a host of benefits including:

* Seamless transition between existing web (Internet) and Web3 infrastructure
* Futureproof design with backward and forward compatibility at its foundation
* Single integration without the need for endless SDKs, APIs and more
* Accessible, compliant and secure infrastructure

### Why Use D3?

[**D3** **Reverse Resolution**](/resolve-d3-names#reverse-resolution) offers a powerful way to make blockchain interactions more human-readable and intuitive. By mapping wallet addresses to domain names, D3 provides enhanced transparency and usability for decentralized applications and crypto transactions.


# Possible Future Use Cases

Here you can find some common use cases that can be addressed by integrating with D3. Click on one of the sections below to read more.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Fractional Ownership of Names</td><td></td><td></td><td><a href="/pages/AuS8pdDahitCLWeDjiun">/pages/AuS8pdDahitCLWeDjiun</a></td></tr><tr><td>Liquidity Pool for Trading Strategies</td><td></td><td></td><td><a href="/pages/VyCpj8V5XlSTYlFsi1hT">/pages/VyCpj8V5XlSTYlFsi1hT</a></td></tr></tbody></table>


# Fractional Ownership of Names

## Fractional Ownership for Names

With [D3’s APIs](/channel-partner-integrations/d3-api), you can enable **fractional ownership** of highly valuable domain names. This use case allows users to pool liquidity together, acquire premium top-level domains (TLDs), and build a diversified portfolio of domains that can be traded or reserved. Developers can set up decentralized governance using DAOs (e.g., Maker or Aave), where governance tokens are used to decide on domain acquisitions and management.

### Overview

Fractional ownership makes it easier for groups of users to own costly assets by splitting ownership through a DAO structure. By pooling liquidity and using governance mechanisms, multiple individuals can collectively invest in high-value domains. The DAO can also choose to reserve certain names, holding them back from sale if the group sees long-term potential.

### How to Build This

With D3’s **Sales API**, fractional ownership models can be seamlessly integrated into your DAO framework, allowing domains to be bought, sold, and reserved as a group.

**Key API Endpoints:**

* **Search for Premium Domains**: Discover high-value domains to add to the DAO’s portfolio.

  <pre class="language-bash"><code class="lang-bash"><strong>GET /v1/partner/search
  </strong></code></pre>
* **Purchase Domains as a Group**: Use the pooled liquidity to make purchases.

  <pre class="language-bash"><code class="lang-bash"><strong>POST /v1/partner/purchase
  </strong></code></pre>
* **Mint Names**: Allows minting of names on primary sale

  ```bash
  POST /v1/partner/mint
  ```

#### Example Flow

1. **Create a DAO**: Set up a DAO using a protocol like **Maker** or **Aave**. Pool liquidity from members and distribute governance tokens that represent each member’s voting power.
2. **Acquire Domains**: The DAO can acquire valuable domain names. Decisions about purchases are made collectively through governance token voting.
3. **Hold or Trade Domains**: The DAO manages the portfolio, choosing whether to sell domains for profit or hold them for future appreciation.&#x20;
4. **Distribute Returns**: Profits from sold domains are distributed proportionally to the liquidity providers based on their initial investments and governance token holdings.

### Benefits

* **Democratize Domain Ownership**: Allow multiple individuals to invest in premium domains that would be cost prohibitive for one person to acquire.
* **DAO Governance**: The use of governance tokens enables fair decision-making and participation in the management of the domain portfolio.
* **Diversified Portfolio**: Build a diversified portfolio of domains that can be traded or reserved for future gains, ensuring a stable and sustainable model for profit.

#### Why Use D3?

[D3's API ](/channel-partner-integrations/d3-api)provides the perfect infrastructure for enabling fractional ownership models. With robust integration offerings, D3 is the ideal platform to power decentralized domain acquisition and management.


# Liquidity Pool for Trading Strategies

## Liquidity Pool for Trading Strategies

D3 makes it possible to create a **liquidity pool** where users can deposit funds, and pool owners utilize these funds to buy and sell domain names. This use case is perfect for those looking to automate domain trading strategies and generate returns for liquidity providers through a share of the trading profits.

### Overview

By integrating the [D3 API](/channel-partner-integrations/d3-api), developers can build a liquidity pool for trading strategies, offering liquidity providers a seamless way to invest in domain trading without having to participate directly. Here's how it works:

1. **Liquidity Providers Deposit Funds**: Users deposit money into a shared liquidity pool.
2. **Pool Owner Executes Trades**: The pool owner uses these funds to buy and sell names.
3. **Generate Yield**: Profits from the trades are deposited back into the pool and shared proportionally with the liquidity providers.
4. **Withdraw Earnings**: Liquidity providers can withdraw their principal and accrued yield at any time, similar to traditional DeFi liquidity pools.

### How to Build This

You can build this system using [D3's API](/channel-partner-integrations/d3-api) to automate domain purchases and sales while managing liquidity flows.

**Key API Endpoints:**

* **Search for Premium Domains**: Discover high-value domains to add to the DAO’s portfolio.

  <pre class="language-bash"><code class="lang-bash"><strong>GET /v1/partner/search
  </strong></code></pre>
* **Purchase Domains as a Group**: Use the pooled liquidity to make purchases.

  <pre class="language-bash"><code class="lang-bash"><strong>POST /v1/partner/purchase
  </strong></code></pre>
* **Mint Names**: Allows minting of names on primary sale

  ```bash
  POST /v1/partner/mint
  ```

#### Example Flow

1. **User Deposits Funds**: Liquidity providers send their funds to the pool via a smart contract or centralized application.
2. **Pool Buys Domains**: The pool owner uses the APIs to search for well priced domain names and makes purchases.
3. **Pool Sells Domains**: When prices rise or predefined triggers are met, the pool sells the domains at a profit.
4. **Yield Distribution**: Profits are distributed among liquidity providers based on their initial contributions, and they can withdraw funds at any time.

### Benefits

* **Trading Strategy**: Users gain access to a diversified domain trading strategy without needing to manage individual trades.
* **Automated Yield**: Liquidity providers earn passive yield based on the pool owner’s trading performance.
* **API-Driven Automation**: Fully automate the buying, selling, and yield distribution processes using D3’s powerful API suite.

### Why Use D3?

D3’s **APIs** provide all the tools you need to build, manage, and scale a liquidity pool for domain trading. With fast transaction processing and access to a broad marketplace of domain names, D3 is the ideal platform for building domain trading strategies that generate consistent returns.


# 🚀 D3 is now Interstellar

Your Domains, Upgraded: Move from D3.app to Interstellar.xyz

Interstellar is the next evolution of D3.app, designed to give you the most modern experience for buying, managing, and using blockchain domains and names. Built from the ground up with modern blockchain infrastructure, Interstellar unlocks entirely new use cases that weren't possible before, while significantly improving the experience for existing products like trading. All your name tokens are coming with us—this is simply a better, more capable home for everything you already own and your identity across web3 communities.

## What does it mean for me?

### 🔒Your D3 account will keep working&#x20;

You don't need to create a new account or reconnect your wallet. Simply visit interstellar.xyz and log in the same way you always have. All your account settings, preferences, and history are preserved. D3 and Interstellar both utilize Doma wallets, enabling seamless portability of your identity and domains across all chains and apps.

### 🌐 Your name tokens are safe

Every name token you own remains in your wallet, exactly where it's always been. Nothing changes about your ownership or custody. These tokens will be automatically upgraded to be part of [Doma Protocol](https://www.doma.xyz), unlocking even more features and better infrastructure on Interstellar. This will require no changes from your side.

### ⏰ When will this happen?

We will begin the upgrade on October 8th and complete the migration by the end of October. You will receive an email as the upgrade begins. At this point, d3.app will start pointing to interstellar.xyz.

## What's new?

### 🌎 Support for Domains using Doma Protocol

Interstellar now supports full domain functionality through Doma Protocol. This means you can register, manage, and use traditional domains (like .com, .xyz, .ai etc.) alongside your name tokens—all in one place. Domains work seamlessly across chains and integrate with the same wallet infrastructure you're already using.

### ⛓️ Fully onchain names and domains

Everything is now truly onchain. Your names and domains aren't just represented onchain—they're fully composable, programmable, and portable across any app or chain that supports Doma Protocol. This unlocks new use cases like using your domain as your identity across multiple dApps, or building apps that interact directly with your domains.

### 🛒 Better marketplace experience

We've partnered with [Doma marketplace](https://dashboard.doma.xyz/) to bring you a completely rebuilt trading experience focused on speed, discoverability, and liquidity. Steep fees and slow transfers are gone—replaced by instant trading and a seamless experience. Discover names and domains faster with improved search, filtering, and tools built for both casual users and serious traders. And this is just the start—more marketplace features and integrations are coming in the months ahead.

## Your migration checklist

### 🔖 Update your bookmarks

Change your bookmarks from d3.app to **interstellar.xyz**. D3.app will redirect automatically after October 8th, but updating now ensures a smooth transition.

### 📝 Relist your names

Your old D3 listings won't automatically carry over to the new marketplace. To make your names available for trading on Interstellar, you'll need to relist them on Doma—the marketplace trusted by the largest registrars to bring domains onchain with instant settlement and multi-chain support.

1. Visit interstellar.xyz and connect your wallet.
2. Go to your inventory.
3. Select the names you want to list and follow the prompts to list on Doma.

Once listed, your names will be discoverable and tradeable with all the benefits of the new marketplace infrastructure. This includes immediate listing on additional marketplaces and the ability to choose a chain of your choice.&#x20;

We have created a step-by-step [guide](/d3-is-now-interstellar/relist-your-names) for you to relist your names. This is **required** to keep your names listed.&#x20;

## FAQs

### Marketplace - Listing and Sales

<details>

<summary>Why are you upgrading your marketplace?</summary>

Doma-backed Marketplace offers several significant advantages over the D3 Marketplace.

* Instant Settlement: No more accepting offers and waiting for payments. Through a fully onchain experience, Doma offers instant settlement. Each offer accepted leads to immediate sale and transfer of funds, leading to a much better buying and selling experience.
* Lower Fees: Through onchain settlement, Doma significantly lowers the fees. In most cases this should lead to a nearly 60% reduction in fees.
* Largest Coverage: Every name listed on Interstellar through Doma receives the biggest possible audience. This means most visibility across all chains and marketplaces.
* Battle-Tested: Doma is trusted by some of the largest registrars on the Planet and offers the most secure marketplace experience.&#x20;

</details>

<details>

<summary>What happens to my existing offers/listings on D3.app?</summary>

All the listings will be removed on October 8th. You can accept any offers you receive until that date. After October 8th you will need to relist your names manually. All names currently listed will keep receiving offers, but you will need to relist/configure to setup a "Buy Now" price etc. Please use our [guide](/d3-is-now-interstellar/relist-your-names) to migrate your names to the new marketplace.&#x20;

</details>

<details>

<summary>Can I still trade my names on external marketplaces like MagicEden/Opensea?</summary>

Yes, the name tokens are automatically upgraded to Doma Protocol. This doesn't affect your listing on other marketplaces, and they will continue to function as usual. In the future, any updates you make in the Interstellar marketplace will be automatically reflected on OpenSea as well.&#x20;

</details>

<details>

<summary><strong>What happens if I don’t re-list my domains?</strong></summary>

Your domains remain yours and will still appear in the marketplace. This means you may still receive offers from buyers. However, without re-listing you won’t have a fixed “Buy It Now” price. Buyers will only be able to place offers instead of purchasing instantly at your chosen price.

</details>

<details>

<summary><strong>Why do I have to relist? Why can't you migrate?</strong></summary>

Interstellar names and domains use Doma standards. As part of this, all user actions (like listing) require a user-signed transaction. This onchain system provides the most secure and trustworthy listing process. However, it is also incompatible with d3.app's listing process. Sadly, this means as a user, you have to resign and relist.&#x20;

</details>

<details>

<summary><strong>Do I need to list at the same price?</strong></summary>

No, this is a brand new listing. Feel free to list your names at any price. Similarly, you can choose not to list names or list additional names.&#x20;

</details>

### Ownership and Security

<details>

<summary><strong>Do I lose/change ownership of my names and domains?</strong></summary>

No. Your names and domains remain secure in your wallet. Re-listing allows you to make them tradable in the new marketplace. However, all your existing names, accounts, and settings are fully safe.

</details>

<details>

<summary><strong>How does Interstellar Secure my Names and Domains?</strong></summary>

Interstellar uses the [Doma Protocol](https://www.doma.xyz) to offer the most secure tokenization layer. Interstellar uses Doma to immediately mint secure tokens into your wallet. Doma also provides secure wallets that work across most major blockchains; alternatively, you are welcome to bring your own favorite wallets.

</details>

<details>

<summary>I don't see all my names</summary>

Interstellar uses Doma to power your account. Please ensure that you link all your wallets with tokens after logging in. Once connected, you should be able to see your names and domains across all wallets you have linked.

</details>

<details>

<summary>How do I tokenize my names?</summary>

All your names are now automatically tokenized. This means you no longer have to tokenize your names manually.&#x20;

</details>

### Accounts and Chains

<details>

<summary>Which chains do you support?</summary>

Interstellar adds support for additional chains. Name Tokens are still issued only on the chain, they belong to. For domains, you can bring them to a chain of your choice either during purchase or by bridging them at any time.&#x20;

</details>

<details>

<summary>Why do you use Doma login?</summary>

Doma login allows you to create a seamless identity. It provides you with the most secure wallet, while also enabling you to create an identity that works with all apps that are part of the Doma ecosystem.

</details>

<details>

<summary><strong>How do I get paid for my sales?</strong></summary>

All sales proceeds are immediately deposited directly into your wallet. Neither Interstellar nor Doma has access to your funds.&#x20;

</details>

## Need Help?

* Direct Support: Our support team is available at **<support@interstellar.xyz>** for any account-specific or technical issues.
* Community Help: Join [Doma Discord t](https://discord.com/invite/doma)o connect with other domainers, share tips, and stay updated on marketplace developments.

Thanks for being part of this journey.  **Interstellar.xyz** is the next chapter of on-chain domain trading, and we’re excited to have you with us.

Best,\
**Team Interstellar**


# Relist your Names

### Step-by-Step Migration Guide

{% stepper %}
{% step %}

### Start on [www.interstellar.xyz](http://www.interstellar.xyz)

![](/files/4ReK5c0K5zk0P69ryPYj)
{% endstep %}

{% step %}

### Connect your Wallet ![](/files/hgh86eROtlgvVe2i9Sr2)

{% endstep %}

{% step %}

### Navigate to your Portfolio

![](/files/rNQi6BIVeWt6R4ULdEdZ)
{% endstep %}

{% step %}

### Navigate to your domain on Doma ![](/files/HTueVRry3I5GolQr8dmH)

{% endstep %}

{% step %}

### List on Doma

Continue your journey on Doma. Your wallet and account will work seamlessly across both sites.\
![](/files/aVN6S5ZYtcV4axgKZ3hH)
{% endstep %}

{% step %}

### Configure your listing

Customize your listing. You can set a buy now price that will allow for instant trading and immediate payment.\
![](/files/hDUn0JvWCR7QNFEefLk0)
{% endstep %}

{% step %}

### Receive offers from all over web3

Doma shows you offers from all over web3, including marketplaces like OpenSea.

<div align="left" data-full-width="false"><figure><img src="/files/wjUarwnByrUmXj6NCT4P" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}
{% endstepper %}


