Registering a Tag
Build a complete non-custodial tag registration flow in your application.
Registering a tag on TIP creates a permanent Program Derived Address (PDA) on the Solana blockchain. Because TIP is non-custodial, the API constructs an unsigned transaction which the connected wallet signs and broadcasts.
Registration Workflow
1. Authenticate (SIWS) ──> 2. Call register({ tag }) ──> 3. Wallet Signs & BroadcastsRegistration can be self-paid or sponsored:
- Self-paid (default): the connected owner's wallet pays the account rent and network fee. Only the owner needs to sign.
- Sponsored: pass
feePayerto have a separate sponsor wallet cover rent and fees instead, so a user with no SOL can still claim a tag. Because Solana's fee payer is baked into the signed message, this must be decided when the transaction is built, so a sponsored transaction needs signatures from both the owner and the sponsor before it can be submitted.
Complete Code Example
import { TipClient } from "@tagwise/tip-sdk";
async function registerUserTag(client: TipClient, walletAdapter: any, desiredTag: string) {
// Step 1: Ensure client is authenticated via SIWS
if (!client.token) {
await client.connect({
publicKey: walletAdapter.publicKey.toBase58(),
signMessage: async (bytes) => walletAdapter.signMessage(bytes),
});
}
// Step 2: Request unsigned register_tag transaction
const unsignedRes = await client.register({
tag: desiredTag,
wallet: walletAdapter.publicKey.toBase58(), // Optional: defaults to owner pubkey
});
console.log("Unsigned Base64 Transaction:", unsignedRes.transaction);
console.log("Derived Tag PDA:", unsignedRes.pda);
// Step 3: Sign & Submit via SDK or Wallet Adapter
// Option A: Use SDK convenience method (requires rpcUrl in TipClient)
const txSignature = await client.signAndSendTransaction(
unsignedRes.transaction,
walletAdapter
);
console.log("Tag registered! Transaction Signature:", txSignature);
return txSignature;
}Sponsored Registration
// sponsorWallet covers rent and fees; the connected wallet is still
// recorded as the tag's owner.
const unsignedRes = await client.register({
tag: desiredTag,
feePayer: sponsorWallet.publicKey.toBase58(),
});
// Both wallets must sign the same unsigned transaction bytes, in either
// order, before it can be submitted.
const partiallySignedByOwner = await ownerWallet.signTransaction(unsignedRes.transaction);
const fullySigned = await sponsorWallet.signTransaction(partiallySignedByOwner);Ownership Is Unaffected
feePayer only decides who pays. The owner recorded on the tag is always the authenticated wallet from the SIWS session, never the sponsor.
Important Constraints & Errors
Rent Exemption Fee
Whichever wallet pays (the owner by default, or feePayer when sponsored) must hold a minimum SOL balance (approx 0.002 SOL) to cover the network fee and the PDA account's rent-exempt deposit. If that wallet's balance is insufficient, the API responds with a 402 before any transaction is built.
Handling Specific Errors
import {
TagInvalidError,
ForbiddenError,
RateLimitedError,
NoSessionError,
} from "@tagwise/tip-sdk";
try {
await client.register({ tag: "alice" });
} catch (error) {
if (error instanceof TagInvalidError) {
console.error("Tag is malformed, profanity-blocked, or already taken.");
} else if (error instanceof NoSessionError) {
console.error("Must call client.connect() before registering.");
} else if (error instanceof RateLimitedError) {
console.error("Too many registration requests. Please wait.");
}
}