Skip to content

Instantly share code, notes, and snippets.

@jdnichollsc
Created August 29, 2022 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdnichollsc/705a83229868ee1d112f42f05a3971e0 to your computer and use it in GitHub Desktop.
Save jdnichollsc/705a83229868ee1d112f42f05a3971e0 to your computer and use it in GitHub Desktop.
Verify that a request is signed by the owner of the public key (NestJS, ExpressJS and Solana)
import { ApiProperty } from '@nestjs/swagger';
export class UserSignatureDto {
@ApiProperty({ description: 'Wallet base58-encoded public key' })
walletPK: string;
@ApiProperty({ description: 'base58-encoded signature of a unique message' })
signature: string;
}
import {
Controller,
UseGuards,
Req,
Post,
Body,
UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { Request } from 'express';
import nacl from 'tweetnacl';
import { PublicKey } from '@solana/web3.js';
import b58 from 'bs58';
import { UserService } from './user.service';
import { UserSignatureDto } from './user-signature.dto';
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@ApiTags('User')
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@ApiOperation({ summary: `Verify that the request is signed by the owner of the public key` })
@Post('wallet')
async verifySignature(
@Req() req: Request,
@Body() signatureDto: UserSignatureDto,
) {
const { walletPK, signature } = signatureDto;
const message = `UserId: ${req.user.userId}`;
const encodedMessage = new TextEncoder().encode(message);
const hasValidSig = nacl.sign.detached.verify(
encodedMessage,
b58.decode(signature),
new PublicKey(walletPK).toBytes(),
);
if (!hasValidSig) {
throw new UnauthorizedException('Invalid signature');
}
const user = await this.userService.findOneByEmail(req.user.email);
user.walletPK = walletPK;
return await this.userService.update(user.userId, user);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment