Register Signer
How to register a signer for API authentication
Authentication: Register Signer
Before making any authenticated API calls, you need to register a signer. The signer is a private key that will be used to sign transactions on behalf of your account.
Step 1: Generate Signer Key
// Generate a new private key for the signer
const signingKey = generatePrivateKey();
const signerAccount = privateKeyToAccount(signingKey);
const signerAddress = signerAccount.address; // This is your signer addressStep 2: Create Signer Signature
const createSignerSignature = async (
account: `0x${string}`,
authContractAddress: `0x${string}`,
) => {
// Generate a new private key for the signer
const signingKey = generatePrivateKey();
const signerAccount = privateKeyToAccount(signingKey);
const signerAddress = signerAccount.address;
// Create nonce
const nonce = createClientNonce(account);
const domain = getRISExDomain(authContractAddress);
// Sign with the signer's private key
const signingKeySignature = await signerAccount.signTypedData({
domain,
types: { VerifySigner: REGISTER_TYPES.VerifySigner },
message: {
account,
nonce, // Note: nonce is a string, not BigInt
},
primaryType: 'VerifySigner',
});
return {
signerAddress,
signingKeySignature,
signingKey, // Store this securely for future use
nonce,
};
};Step 3: Create Account Signature (User Wallet Signature)
const createAccountSignature = async (
signerAddress: `0x${string}`,
nonce: string,
authContractAddress: `0x${string}`,
// You'll need a wallet provider (like wagmi, ethers, etc.)
signTypedDataAsync: (data: any) => Promise<string>,
) => {
const registerMessage = {
signer: signerAddress,
message: 'Please sign in with your wallet to access RISEx.',
nonce,
expiration: dayjs().add(7, 'day').unix(), // 7 days from now
};
const domain = getRISExDomain(authContractAddress);
// User signs with their wallet
const accountSignature = await signTypedDataAsync({
types: REGISTER_TYPES,
message: {
signer: registerMessage.signer,
message: registerMessage.message,
nonce: BigInt(registerMessage.nonce),
expiration: BigInt(registerMessage.expiration),
},
primaryType: 'RegisterSigner',
domain: domain as any,
});
// Viem returns properly formatted signatures - no additional formatting needed
return {
accountSignature,
registerMessage,
};
};Step 4: Register Signer via API
const registerSigner = async (
account: `0x${string}`,
authContractAddress: `0x${string}`,
signTypedDataAsync: (data: any) => Promise<string>,
) => {
try {
// Step 1: Generate signer and create signer signature
const { signerAddress, signingKeySignature, signingKey, nonce } =
await createSignerSignature(account, authContractAddress);
// Step 2: Get user wallet signature
const { accountSignature, registerMessage } = await createAccountSignature(
signerAddress,
nonce,
authContractAddress,
signTypedDataAsync,
);
// Step 3: Register via API
const response = await apiClient.post('/v1/auth/register-signer', {
account: account,
signer: registerMessage.signer,
message: registerMessage.message,
nonce: registerMessage.nonce,
expiration: registerMessage.expiration.toString(),
account_signature: accountSignature, // Note: uses account_signature, not signature
signer_signature: signingKeySignature, // Note: uses signer_signature, not signature
});
if (response.data) {
console.log('Signer registered successfully:', {
account,
signer: signerAddress,
signingKey, // Store this securely!
expiration: registerMessage.expiration,
});
// IMPORTANT: Store signingKey securely for future API calls
return {
signer: signerAddress,
signingKey, // Keep this secret!
};
}
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Failed to register signer:', error.response?.data?.message || error.message);
} else {
console.error('Failed to register signer:', error);
}
throw error;
}
};Important Notes
- One-time setup: Register signer once per account
- Store securely: Keep the
signingKeyprivate and secure - it authorizes all transactions - Expiration: Signers expire after the expiration time (typically 7 days)
- Re-registration: You may need to re-register if the signer expires