Skip to content

Commit 7a5042b

Browse files
authored
Merge pull request #38 from dimitrov-d/master
Implement RPC module
2 parents 677bcf7 + 711160d commit 7a5042b

File tree

13 files changed

+270
-32
lines changed

13 files changed

+270
-32
lines changed

package-lock.json

Lines changed: 14 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/sdk/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ async function validatePolkadotWalletSignature() {
383383
}
384384

385385
```
386+
386387
## Computing
387388

388389
The Computing module provides functionalities for managing computing contracts, including creating contracts, listing contracts, and interacting with specific contracts for operations like encryption and ownership transfer.
@@ -435,6 +436,42 @@ console.log(
435436
);
436437
```
437438

439+
## RPCs
440+
441+
The RPC module provides functionalities for managing RPC API keys and listing available endpoints. This module is essential for interacting with the Apillon platform's RPC services dynamically.
442+
443+
### Usage example
444+
445+
```typescript
446+
import { Rpc } from '@apillon/sdk';
447+
import { getConfig } from './helpers/helper';
448+
449+
// Initialize the RPC module
450+
const rpc = new Rpc({
451+
key: 'yourApiKey',
452+
secret: 'yourApiSecret',
453+
});
454+
455+
// Create a new API key
456+
const apiKey = await rpc.createApiKey({
457+
name: 'Test API Key',
458+
description: 'Test Description',
459+
});
460+
console.log('API Key created:', apiKey.name);
461+
462+
// List all API keys
463+
const { items } = await rpc.listApiKeys();
464+
console.log('Total API Keys:', items.length);
465+
466+
// Get a specific API key by ID
467+
const apiKey = await rpc.apiKey(apiKeyId).get();
468+
console.log('API Key UUID:', apiKey.uuid);
469+
470+
// List all available endpoints
471+
const endpoints = await rpc.listEndpoints();
472+
console.log('Total Endpoints:', endpoints.length);
473+
```
474+
438475
## Social
439476

440477
The Social module provides functionalities for managing social hubs and channels within the Apillon platform. This includes creating, listing, and interacting with hubs and channels. In the background it utilizes Grill.chat, a mobile-friendly, anonymous chat application powered by Subsocial.

packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@apillon/sdk",
33
"description": "▶◀ Apillon SDK for NodeJS ▶◀",
4-
"version": "3.5.0",
4+
"version": "3.6.0",
55
"author": "Apillon",
66
"license": "MIT",
77
"main": "./dist/index.js",

packages/sdk/src/docs-index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export * from './types/storage';
55
export * from './types/identity';
66
export * from './types/computing';
77
export * from './types/social';
8+
export * from './types/cloud-functions';
9+
export * from './types/indexer';
10+
export * from './types/rpc';
11+
812
export * from './lib/apillon';
913
export * from './modules/storage/storage';
1014
export * from './modules/storage/storage-bucket';
@@ -28,3 +32,5 @@ export * from './modules/cloud-functions/cloud-function';
2832
export * from './modules/cloud-functions/cloud-function-job';
2933
export * from './modules/indexing/indexing';
3034
export * from './modules/indexing/indexer';
35+
export * from './modules/rpc/rpc';
36+
export * from './modules/rpc/rpc-api-key';

packages/sdk/src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ export * from './types/hosting';
44
export * from './types/storage';
55
export * from './types/identity';
66
export * from './types/social';
7+
export * from './types/cloud-functions';
8+
export * from './types/indexer';
9+
export * from './types/rpc';
10+
711
export * from './lib/apillon';
812
export * from './lib/common';
13+
914
export * from './modules/storage/storage';
1015
export * from './modules/hosting/hosting';
1116
export * from './modules/nft/nft';
@@ -15,4 +20,4 @@ export * from './modules/social/social';
1520
export * from './modules/project/project';
1621
export * from './modules/cloud-functions/cloud-functions';
1722
export * from './modules/indexing/indexing';
18-
export * from './modules/indexing/indexer';
23+
export * from './modules/rpc/rpc';

packages/sdk/src/lib/apillon.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ export interface ApillonConfig {
3030
debug?: boolean;
3131
}
3232

33+
export interface ICreateApillonModel {
34+
/**
35+
* Name of the model object
36+
*/
37+
name: string;
38+
/**
39+
* Description of the model object
40+
*/
41+
description: string;
42+
}
43+
3344
export class ApillonModule {
3445
protected config: ApillonConfig;
3546

packages/sdk/src/modules/cloud-functions/cloud-functions.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { ApillonModule } from '../../lib/apillon';
1+
import { ApillonModule, ICreateApillonModel } from '../../lib/apillon';
22
import { ApillonApi } from '../../lib/apillon-api';
33
import { constructUrlWithQueryParams } from '../../lib/common';
44
import { IApillonList, IApillonPagination } from '../../types/apillon';
5-
import { ICreateCloudFunction } from '../../types/cloud-functions';
65
import { CloudFunction } from './cloud-function';
76
import { CloudFunctionJob } from './cloud-function-job';
87

@@ -38,11 +37,11 @@ export class CloudFunctions extends ApillonModule {
3837

3938
/**
4039
* Creates a new cloud function based on the provided data.
41-
* @param {ICreateCloudFunction} data Data for creating the cloud function.
40+
* @param {ICreateApillonModel} data Data for creating the cloud function.
4241
* @returns {CloudFunction} Newly created cloud function.
4342
*/
4443
public async createCloudFunction(
45-
data: ICreateCloudFunction,
44+
data: ICreateApillonModel,
4645
): Promise<CloudFunction> {
4746
const cloudFunction = await ApillonApi.post<
4847
CloudFunction & { functionUuid: string }
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { ApillonModel } from '../../lib/apillon';
2+
3+
export class RpcApiKey extends ApillonModel {
4+
/**
5+
* Unique identifier of the RPC API key.
6+
*/
7+
public id: number = null;
8+
9+
/**
10+
* Name of the RPC API key.
11+
*/
12+
public name: string = null;
13+
14+
/**
15+
* Description of the RPC API key.
16+
*/
17+
public description: string = null;
18+
19+
/**
20+
* Unique identifier of the project.
21+
*/
22+
public projectUuid: string = null;
23+
24+
/**
25+
* Unique identifier of the RPC API key, used for RPC calls.
26+
*/
27+
public uuid: string = null;
28+
29+
/**
30+
* Array of favorite URLs for the RPC API key.
31+
*/
32+
public urls: string[] = [];
33+
34+
/**
35+
* Constructor which should only be called via Rpc class.
36+
* @param id Unique identifier of the RPC API key.
37+
* @param data Data to populate RPC API key with.
38+
*/
39+
constructor(id: number, data?: Partial<RpcApiKey>) {
40+
super(id.toString());
41+
this.API_PREFIX = `/rpc/api-key/${id}`;
42+
this.populate(data);
43+
}
44+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { ApillonModule, ICreateApillonModel } from '../../lib/apillon';
2+
import { ApillonApi } from '../../lib/apillon-api';
3+
import { constructUrlWithQueryParams } from '../../lib/common';
4+
import { IApillonList, IApillonPagination } from '../../types/apillon';
5+
import { RpcEndpoint } from '../../types/rpc';
6+
import { RpcApiKey } from './rpc-api-key';
7+
8+
export class Rpc extends ApillonModule {
9+
/**
10+
* API URL for RPC module.
11+
*/
12+
private API_PREFIX = '/rpc';
13+
14+
/**
15+
* List all API keys for RPC.
16+
* @param {IApillonPagination} params - The query parameters for filtering API keys.
17+
* @returns The list of API keys.
18+
*/
19+
public async listApiKeys(
20+
params?: IApillonPagination,
21+
): Promise<IApillonList<RpcApiKey>> {
22+
const url = constructUrlWithQueryParams(
23+
`${this.API_PREFIX}/api-key`,
24+
params,
25+
);
26+
27+
const data = await ApillonApi.get<IApillonList<RpcApiKey>>(url);
28+
29+
return {
30+
...data,
31+
items: data.items.map((apiKey) => new RpcApiKey(apiKey.id, apiKey)),
32+
};
33+
}
34+
35+
/**
36+
* Create a new API key for RPC module.
37+
* @param {ApillonApiCreateRpcApiKeyDto} data - The data for creating an API key.
38+
* @returns The created API key.
39+
*/
40+
public async createApiKey(data: ICreateApillonModel): Promise<RpcApiKey> {
41+
const apiKey = await ApillonApi.post<any>(
42+
`${this.API_PREFIX}/api-key`,
43+
data,
44+
);
45+
return new RpcApiKey(apiKey.uuid, apiKey);
46+
}
47+
48+
/**
49+
* Get all available endpoints for the RPC service.
50+
* @returns The list of endpoints.
51+
*/
52+
public async listEndpoints(): Promise<RpcEndpoint[]> {
53+
return await ApillonApi.get<RpcEndpoint[]>(`${this.API_PREFIX}/endpoints`);
54+
}
55+
56+
/**
57+
* @param id Unique API key identifier.
58+
* @returns An empty instance of RpcApiKey.
59+
*/
60+
public apiKey(id: number): RpcApiKey {
61+
return new RpcApiKey(id, null);
62+
}
63+
}

packages/sdk/src/tests/rpc.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { Rpc } from '../modules/rpc/rpc';
2+
import { RpcApiKey } from '../modules/rpc/rpc-api-key';
3+
import { getConfig } from './helpers/helper';
4+
5+
describe('Rpc Module tests', () => {
6+
let rpc: Rpc;
7+
let apiKeyId: number;
8+
9+
beforeAll(() => {
10+
rpc = new Rpc(getConfig());
11+
});
12+
13+
test('Create new API key', async () => {
14+
const apiKeyData = {
15+
name: 'Test API Key',
16+
description: 'Test Description',
17+
};
18+
const apiKey = await rpc.createApiKey(apiKeyData);
19+
20+
expect(apiKey).toBeInstanceOf(RpcApiKey);
21+
expect(apiKey.name).toEqual(apiKeyData.name);
22+
expect(apiKey.description).toEqual(apiKeyData.description);
23+
expect(apiKey.uuid).toBeTruthy();
24+
expect(apiKey.id).toBeTruthy();
25+
26+
apiKeyId = apiKey.id;
27+
});
28+
29+
test('List API keys', async () => {
30+
const { items } = await rpc.listApiKeys();
31+
32+
expect(items.length).toBeGreaterThanOrEqual(0);
33+
items.forEach((apiKey) => {
34+
expect(apiKey).toBeInstanceOf(RpcApiKey);
35+
expect(apiKey.name).toBeTruthy();
36+
expect(apiKey.uuid).toBeTruthy();
37+
expect(apiKey.id).toBeTruthy();
38+
});
39+
});
40+
41+
test('Get specific API key', async () => {
42+
const apiKey = await rpc.apiKey(apiKeyId).get();
43+
44+
expect(apiKey).toBeInstanceOf(RpcApiKey);
45+
expect(apiKey.id).toEqual(apiKeyId);
46+
});
47+
48+
test('List endpoints', async () => {
49+
const endpoints = await rpc.listEndpoints();
50+
51+
expect(Array.isArray(endpoints)).toBeTruthy();
52+
expect(endpoints.length).toBeGreaterThanOrEqual(0);
53+
54+
endpoints.forEach((endpoint) => {
55+
expect(endpoint).toMatchObject({
56+
id: expect.any(Number),
57+
name: expect.any(String),
58+
imageUrl: expect.any(String),
59+
type: expect.any(String),
60+
version: expect.any(String),
61+
networkName: expect.any(String),
62+
networkId: expect.any(Number),
63+
});
64+
});
65+
});
66+
});

0 commit comments

Comments
 (0)