Skip to content

Commit

Permalink
feat: ipns url (#272)
Browse files Browse the repository at this point in the history
* feature/ipns-url: Returns IPNS url for uloaded constitution

* feature/ipns-url: minor cahnges

* feature/ipns-url: changed env variable

* feature/ipns-url: disabled open api for uploading the constitution file
  • Loading branch information
BEdev24 authored Aug 19, 2024
1 parent ccb1797 commit 3622291
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 4 deletions.
30 changes: 28 additions & 2 deletions backend/postman/CC Portal develop.postman_collection.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"info": {
"_postman_id": "374f247a-1ea9-4c6a-8a4f-5b5eaa052036",
"name": "CC Portal develop",
"_postman_id": "e842d76b-56e2-476d-b31d-bbeffd0853bc",
"name": "CC Portal develop Copy",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "20133713"
},
Expand Down Expand Up @@ -623,6 +623,32 @@
}
},
"response": []
},
{
"name": "Get IPNS URL",
"request": {
"method": "GET",
"header": [
{
"key": "Authorization",
"value": "{{accessToken}}",
"type": "text"
}
],
"url": {
"raw": "{{base-url}}/api/constitution/ipns/url",
"host": [
"{{base-url}}"
],
"path": [
"api",
"constitution",
"ipns",
"url"
]
}
},
"response": []
}
]
},
Expand Down
20 changes: 20 additions & 0 deletions backend/src/constitution/api/constitution.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
HttpStatus,
} from '@nestjs/common';
import {
ApiBearerAuth,
ApiBody,
ApiConsumes,
ApiOperation,
Expand All @@ -25,6 +26,7 @@ import { PermissionGuard } from 'src/auth/guard/permission.guard';
import { FileInterceptor } from '@nestjs/platform-express';
import { ConstitutionMetadataResponse } from './response/constitution-metadata.response';
import { getFileValidator } from '../pipe/fileValidatorPipe';
import { ApiConditionalExcludeEndpoint } from 'src/common/decorators/api-conditional-exclude-endpoint.decorator';

@ApiTags('Constitution')
@Controller('constitution')
Expand Down Expand Up @@ -60,6 +62,7 @@ export class ConstitutionController {
return await this.constitutionFacade.getConstitutionFileByCid(cid);
}

@ApiConditionalExcludeEndpoint()
@ApiOperation({ summary: 'Store constitution file' })
@ApiBody({
schema: {
Expand Down Expand Up @@ -125,4 +128,21 @@ export class ConstitutionController {
async getAllConstitutionMetadata(): Promise<ConstitutionMetadataResponse[]> {
return this.constitutionFacade.getAllConstitutionMetadata();
}

@ApiConditionalExcludeEndpoint()
@ApiOperation({
summary: 'Get IPNS URL for constitution',
})
@ApiBearerAuth('JWT-auth')
@ApiResponse({
status: 200,
description: 'Returns a IPNS URL',
type: ConstitutionMetadataResponse,
})
@Permissions(PermissionEnum.ADD_CONSTITUTION)
@UseGuards(JwtAuthGuard, PermissionGuard)
@Get('ipns/url')
async getIpnsUrl() {
return await this.constitutionFacade.getIpnsUrl();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';

export class ConstitutionIpnsUrlResponse {
@ApiProperty({
description: 'IPNS URL related to a deployed Constitution',
example:
'https://ipfs.io/ipns/QmVcVq1zssBLdcuw8nM19VYiLWjt9cMQSUrHSwVd5oY4s2',
})
@Expose({ name: 'ipns_url' })
ipnsUrl: string;
}
6 changes: 6 additions & 0 deletions backend/src/constitution/facade/constitution.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ConstitutionDto } from 'src/redis/dto/constitution.dto';
import { ConstitutionService } from '../services/constitution.service';
import { IpfsService } from 'src/ipfs/services/ipfs.service';
import { ConstitutionMetadataResponse } from '../api/response/constitution-metadata.response';
import { ConstitutionIpnsUrlResponse } from '../api/response/constitutio-ipns-url.response';

@Injectable()
export class ConstitutionFacade {
Expand Down Expand Up @@ -63,4 +64,9 @@ export class ConstitutionFacade {
ConstitutionMapper.ipfsMetadataDtoToConstitutionResponse(metadataDto),
);
}

async getIpnsUrl(): Promise<ConstitutionIpnsUrlResponse> {
const ipnsUrl = await this.ipfsService.getIpnsUrl();
return ConstitutionMapper.ipnsUrlToResponse(ipnsUrl);
}
}
7 changes: 7 additions & 0 deletions backend/src/constitution/mapper/constitution.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CreateConstitutionDto } from '../dto/create-constitution.dto';
import { IpfsContentDto } from 'src/ipfs/dto/ipfs-content.dto';
import { IpfsMetadataDto } from 'src/ipfs/dto/ipfs-metadata.dto';
import { ConstitutionMetadataResponse } from '../api/response/constitution-metadata.response';
import { ConstitutionIpnsUrlResponse } from '../api/response/constitutio-ipns-url.response';
import { IPFS_PUBLIC_URL } from 'src/common/constants/ipfs.constants';

export class ConstitutionMapper {
Expand Down Expand Up @@ -48,4 +49,10 @@ export class ConstitutionMapper {

return constitutionResponse;
}

static ipnsUrlToResponse(ipnsUrl: string): ConstitutionIpnsUrlResponse {
const constitutionIpnsUrlResponse = new ConstitutionIpnsUrlResponse();
constitutionIpnsUrlResponse.ipnsUrl = ipnsUrl;
return constitutionIpnsUrlResponse;
}
}
15 changes: 15 additions & 0 deletions backend/src/ipfs/services/ipfs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,19 @@ export class IpfsService {
contents: content,
};
}

async getIpnsUrl(): Promise<string> {
const apiLink =
this.configService.getOrThrow('IPFS_SERVICE_URL') + '/ipfs/ipns/url';
try {
const response = await axios.get(apiLink);
const ipnsUrl = response.data;
return ipnsUrl;
} catch (error) {
this.logger.error(`Error when getting IPNS URL from IPFS: ${error}`);
throw new InternalServerErrorException(
`Error when getting IPNS URL from IPFS service`,
);
}
}
}
4 changes: 3 additions & 1 deletion ipfs-service/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ ANNOUNCE_TCP_ADDRESS='/ip4/<your-public-ip>/tcp/4001'
ANNOUNCE_WS_ADDRESS='/ip4/<your-public-ip>/tcp/4003/ws'

IPFS_PUBLIC_URL='https://ipfs.io/ipfs/'
IPNS_PUBLIC_URL='https://ipfs.io/ipns/'
IPNS_PUBLIC_URL='https://ipfs.io/ipns/'

IPNS_CONSTITUTION_KEY_NAME='some-key-name'
5 changes: 5 additions & 0 deletions ipfs-service/src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ export class AppController {
}
return doc
}

@Get('ipns/url')
async getIpnsUrl(): Promise<string> {
return await this.appService.getIpnsUrl();
}
}
10 changes: 9 additions & 1 deletion ipfs-service/src/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class AppService implements OnModuleInit {

async getIpns() {
this.ipns = ipns(this.helia);
const keyName = 'my-key11';
const keyName = process.env.IPNS_CONSTITUTION_KEY_NAME;
const existingKeys = await this.helia.libp2p.services.keychain.listKeys();
// if keyName already exists
if (existingKeys.some((x) => x.name === keyName)) {
Expand Down Expand Up @@ -264,4 +264,12 @@ export class AppService implements OnModuleInit {

attemptToProvide();
}

async getIpnsUrl(): Promise<string> {
if (!this.ipnsPeerId) {
throw new InternalServerErrorException(`IPNS Peer Id not exists`);
}
const ipnsUrl = process.env.IPNS_PUBLIC_URL + this.ipnsPeerId.toString()
return ipnsUrl;
}
}

0 comments on commit 3622291

Please sign in to comment.