Skip to main content

Register names

Registration binds a short name (e.g. john.saf) to the signer's addr_safro on chain. Default fee: 50 SAF (50000000 usaf), routed to the dev module wallet.

v1 scope

Testnet v1 supports name registration only. Phone linking (linkPhone) is Phase 2 and not in the current wasm build. See contract PHONE_LINKING.

Registration flow

SDK: registerName

import { SafHandle } from '@safrochaindev/safhandle';
import { useChain } from '@cosmos-kit/react';

const safHandle = new SafHandle({ network: 'safrochain-testnet' });
const { getOfflineSigner } = useChain('safro-testnet-1');

async function registerJohn() {
const config = await safHandle.getConfig();
console.log('Fee:', config.nameRegistrationFeeUsaf, 'usaf');

const signer = await getOfflineSigner();
const tx = await safHandle.registerName('john', {
signer,
gas: 'auto',
memo: 'register john.saf',
});
console.log(tx.transactionHash);
}

CosmJS: MsgExecuteContract

Direct execute when not using the SDK wrapper:

import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx';
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate';

const CONTRACT = 'addr_safro1j6n2q333gy80pmpd6avss32y4nhd8deayv8m9x4uazt6zkdczk9sxjfun6';
const FEE_AMOUNT = '50000000'; // 50 SAF

const msg = {
typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
value: MsgExecuteContract.fromPartial({
sender: address,
contract: CONTRACT,
msg: new TextEncoder().encode(
JSON.stringify({ register_name: { name: 'john.saf' } }),
),
funds: [{ denom: 'usaf', amount: FEE_AMOUNT }],
}),
};

const client = await SigningCosmWasmClient.connectWithSigner(RPC, offlineSigner, {
gasPrice: { denom: 'usaf', amount: '0.05' },
});
const result = await client.signAndBroadcast(address, [msg], 'auto');

Funds must exactly match name_registration_fee_usaf from getConfig() or a config query.

Registration UX checklist

StepRecommendation
InputLive isValidName() validation
FeeDisplay 50 SAF from getConfig()
ConfirmShow normalized name john.saf + fee + signer address
SuccessLink to explorer tx
ErrorsMap NameTaken, ReservedName, InsufficientFee to clear copy

Common contract errors: CONTRACT_API.

Phone linking (Phase 2)

When the phone feature ships:

await safHandle.linkPhone('+243899123456', {
signer: offlineSigner,
gas: 'auto',
});
// Default fee: 100 SAF (100000000 usaf)

Warn users that phone numbers are public on chain. Verification flow: SDK phone verification.

CLI (dev / ops)

CONTRACT=addr_safro1j6n2q333gy80pmpd6avss32y4nhd8deayv8m9x4uazt6zkdczk9sxjfun6

safrochaind tx wasm execute "$CONTRACT" \
'{"register_name":{"name":"john.saf"}}' \
--amount 50000000usaf \
--from dev \
--chain-id safro-testnet-1 \
--node https://rpc.testnet.safrochain.com:443 \
--gas auto --gas-adjustment 1.3 --gas-prices 0.05usaf \
-y

Next steps