Skip to content
This repository was archived by the owner on Aug 27, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
247 changes: 168 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,88 @@
![Namespace Ninja](https://namespace.fra1.cdn.digitaloceanspaces.com/brand/logo_small.png)
# Namespace-SDK

A Typescript library used to interact with Namespace contracts and APIs.
It uses Viem under the hood and can be used to:
* Find names listed on the Namespace platform
* Check the availability of subnames
* Mint subnames
A TypeScript SDK for interacting with Namespace - a platform for managing ENS names and subnames. Built on top of [Viem](https://viem.sh), this SDK enables you to:
* List and manage ENS subnames
* Check subname availability across multiple chains
* Mint ENS subnames with custom records
* Interact with Namespace smart contracts

This is the initial version, expect many more functionalities in the future!
> **Note**: This project is in early stages and is under active development.

# Installation

Use a package manager to install the library into your project
Install using your preferred package manager:

Yarn
```bash
yarn add namespace-sdk
```
Npm
```bash
# pnpm
pnpm add namespace-sdk

# npm
npm install namespace-sdk

# yarn
yarn add namespace-sdk
```
**Note**: We recommend using [pnpm](https://pnpm.io/) due to its better performance and smaller bundle size.

# Usage

## Prerequisites

# Getting started
### Listing an ENS Name

First, we can create a simple NamespaceClient and specify the chainID. The chain id specifies a chain on which read/write blockchain operations happen. If we list our name on a Mainnet and subnames are minted on Mainnet, we'll have to specify a chainID 1. We will use a sepolia testnet as an example.
Before minting subnames, you need to list your ENS name on the [Namespace platform](https://app.namespace.tech).

The chainID is required since the library supports minting subnames on both Layer 1 and its testnet (Sepolia) but also on Layer 2 (currently, only Base chain is supported).
You can find the required steps by following the [Manager Guide](https://docs.namespace.tech/namespace-platform/manager/listing-an-ens-name#listing-an-ens-name)

## Using the SDK

### Initialize the Client

Create a NamespaceClient instance by specifying the chain you want to interact with.

```typescript
import { createNamespaceClient } from "namespace-sdk";
import { sepolia } from "viem/chains";

// Initialize the Namespace SDK client
const namespaceClient = createNamespaceClient({
chainId: sepolia.id
});
```
# Minting a subname

Minting ENS subnames requires a couple of steps.

## 1. Listing an ENS name
Currently, we support the following chains:
- Ethereum Mainnet
- Sepolia Testnet
- Base
- Base Sepolia Testnet
- Optimism
- Arbitrum

First, we would need to have an ENS name that is listed on the Namespace platform. To do so, visit our [Platform](https://app.namespace.tech) and check
[Manager](https://docs.namespace.tech/namespace-platform/manager)
**Note**: We are actively working on adding support for more chains.

For testing purposes, you can use "namespace-sdk.eth" on the Sepolia chain.
## 2. Generate minting parameters

After we list the ENS name, our platform allows minting subnames under it. We can use a library to check for subname availability and to generate mint transaction parameters.
### Minting ENS Subnames

The minting process consists of two main steps:
1. Check subname availability and generate the required transaction parameters:
```typescript
import { createNamespaceClient, SetRecordsRequest, MintTransactionParameters } from "namespace-sdk";
// Import the Namespace SDK and Viem chains
import { createNamespaceClient, MintTransactionParameters } from "namespace-sdk";
import { sepolia } from "viem/chains";

// Initialize the Namespace SDK client
const namespaceClient = createNamespaceClient({
chainId: sepolia.id,
});

// Define the listed name from the [Namespace Platform](https://docs.namespace.tech/namespace-platform/manager/listing-an-ens-name#listing-an-ens-name) in the previous step
const LISTED_NAME = "namespace-sdk.eth"
const ETH_COIN_TYPE = 60;

// Define the subname to be minted
const SUBNAME_LABEL = "subname"

// Define the minter address
const MINTER_ADDRESS = "0xbe02d5ceAB7296A4E8b516eee578Be75983674e9"

const generateMintingParameters = async (): Promise<MintTransactionParameters> => {

Expand All @@ -69,76 +92,142 @@ const generateMintingParameters = async (): Promise<MintTransactionParameters> =
sepolia.id
);

const subnameLabel = "myfunnylabel";
const minterAddress = "0x6CaBE5E77F90d58600A3C13127Acf6320Bee0aA7"

// Check for name availability
const isNotTaken = await namespaceClient.isSubnameAvailable(
listedName,
subnameLabel
SUBNAME_LABEL
);

if (!isNotTaken) {
throw Error("Subname is already taken!");
}

// Generate mint transcation parameters
const mintDetails = await namespaceClient.getMintTransactionParameters(listedName, {
minterAddress: minterAddress,
subnameLabel: subnameLabel,
subnameOwner: minterAddress,
// Optionaly, we can also set resolver records with the mint transaction
records: {
addresses: [
{
address: minterAddress,
coinType: ETH_COIN_TYPE
}
],
texts: [
{
key: "name",
value: "namespace"
}
]
}
minterAddress: MINTER_ADDRESS,
subnameLabel: SUBNAME_LABEL,
subnameOwner: MINTER_ADDRESS,
});
return mintDetails;
};
```
## 3. Send Transaction
Sending a transaction is the last step. Since the library uses Viem under the hood, we will use WalletClient to send a transaction.

2. Execute the Mint Transaction

Use Viem's WalletClient to send the transaction:

```typescript
// Import your wallet and create a Viem Wallet Client
const wallet = privateKeyToAccount("0xYOUR_PRIVATE_KEY_HERE");
const walletClient = createWalletClient({
transport: http(),
chain: sepolia,
account: wallet,
})

// Generate minting parameters
const mintParams = await generateMintingParameters();

// Send transaction
const transactionHash = await walletClient.writeContract({
abi: mintParams.abi,
address: mintParams.contractAddress,
functionName: mintParams.functionName,
args: mintParams.args,
value: mintParams.value,
})

console.log(transactionHash);
```

Full example:
```typescript
// Import the Namespace SDK and Viem chains
import { createNamespaceClient, MintTransactionParameters } from "namespace-sdk";
import { sepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { createWalletClient, http } from "viem";
import { generateMintingParameters } from "./minting";

const sendMintTransaction = async () => {

// Import your wallet and create a Viem Wallet Client
const wallet = privateKeyToAccount("0xYourWallet");
const walletClient = createWalletClient({
transport: http(),
chain: sepolia,
account: wallet
})

// Generate minting parameters
const mintParams = await generateMintingParameters();

// Send transaction
const transactionHash = await walletClient.writeContract({
abi: mintParams.abi,
address: mintParams.contractAddress,
functionName: mintParams.functionName,
args: mintParams.args,
value: mintParams.value
})

console.log(transactionHash);
}

// Initialize the Namespace SDK client
const namespaceClient = createNamespaceClient({
chainId: sepolia.id,
});

// Define the listed name from the [Namespace Platform](https://docs.namespace.tech/namespace-platform/manager/listing-an-ens-name#listing-an-ens-name) in the previous step
const LISTED_NAME = "namespace-sdk.eth"

// Define the subname to be minted
const SUBNAME_LABEL = "subname"

// Define the minter address
const MINTER_ADDRESS = "0xbe02d5ceAB7296A4E8b516eee578Be75983674e9"

const generateMintingParameters = async (): Promise<MintTransactionParameters> => {

// Get listed name from namespace api
const listedName = await namespaceClient.getListedName(
LISTED_NAME,
sepolia.id
);

// Check for name availability
const isNotTaken = await namespaceClient.isSubnameAvailable(
listedName,
SUBNAME_LABEL
);

if (!isNotTaken) {
throw Error("Subname is already taken!");
}

// Generate mint transcation parameters
const mintDetails = await namespaceClient.getMintTransactionParameters(listedName, {
minterAddress: MINTER_ADDRESS,
subnameLabel: SUBNAME_LABEL,
subnameOwner: MINTER_ADDRESS,
});
return mintDetails;
};

// Import your wallet and create a Viem Wallet Client
const wallet = privateKeyToAccount("0xYOUR_PRIVATE_KEY_HERE");
const walletClient = createWalletClient({
transport: http(),
chain: sepolia,
account: wallet,
})

// Generate minting parameters
const mintParams = await generateMintingParameters();

// Send transaction
const transactionHash = await walletClient.writeContract({
abi: mintParams.abi,
address: mintParams.contractAddress,
functionName: mintParams.functionName,
args: mintParams.args,
value: mintParams.value,
})

console.log(transactionHash);
```
**Note**: We recommend setting a custom RPC URL for the chain you are interacting with. You can do so by adding an argument to the http() function:
```typescript
const walletClient = createWalletClient({
transport: http('https://eth-sepolia.g.alchemy.com/v2/ALCHEMY_API_KEY'),
chain: sepolia,
account: wallet,
})
```


## Contributing

Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting PRs.

## License

MIT License - see the [LICENSE](LICENSE) file for details.

## Authors
[artii.eth](https://github.com/nenadmitt)
- [artii.eth](https://github.com/nenadmitt)
18 changes: 9 additions & 9 deletions src/clients/types/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ const Types = {
};

export interface AuthTokenMessage {
app: string
issued: number,
message: string,
nonce: string,
principal: Address,
app: string
issued: number,
message: string,
nonce: string,
principal: Address,
}

export interface AuthTokenResponse {
accessToken: string
refreshToken: string
accessToken: string
refreshToken: string
}

export interface AuthTokenRequest {
Expand All @@ -34,6 +34,6 @@ export interface AuthTokenRequest {
}

export const AuthTypedData = {
Domain,
Types
Domain,
Types,
}
27 changes: 13 additions & 14 deletions src/clients/types/listings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@ import { L2Chain, MainChain } from "."
import { Address } from "viem"

export interface ListingRequest {
listingType?: ListingType
network: MainChain
tokenNetwork?: L2Chain
owner?: Address
page?: number
size?: number
listingType?: ListingType
network: MainChain
tokenNetwork?: L2Chain
owner?: Address
page?: number
size?: number
}

export interface Listing {
label: string;
fullName: string;
node: string;
network: MainChain;
listingType?: ListingType
registryNetwork?: L2Chain
label: string;
fullName: string;
node: string;
network: MainChain;
listingType?: ListingType
registryNetwork?: L2Chain
}


export type ListingType = "sellUnruggable" | "l2"
export type ListingType = "sellUnruggable" | "l2"