Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/api/actor.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import {type ActorParameters} from '@junobuild/admin';
import {isNullish, nonNullish} from '@junobuild/utils';
import {red} from 'kleur';
import {getToken} from '../configs/cli.config';
import {REVOKED_CONTROLLERS} from '../constants/constants';
import {getProcessToken} from '../utils/process.utils';
import {initAgent} from './agent.api';

export const actorParameters = async (): Promise<ActorParameters> => {
export const actorParameters = async (): Promise<
Omit<ActorParameters, 'agent'> & Required<Pick<ActorParameters, 'agent'>>
> => {
const token = getProcessToken() ?? (await getToken());

if (isNullish(token)) {
Expand All @@ -16,13 +18,16 @@ export const actorParameters = async (): Promise<ActorParameters> => {

const identity = Ed25519KeyIdentity.fromParsedJson(token);

if (REVOKED_CONTROLLERS.includes(identity.getPrincipal().toText())) {
throw new Error('The controller has been revoked for security reason!');
}

return {
const params: Omit<ActorParameters, 'agent'> = {
identity,
fetch,
...(nonNullish(process.env.CONTAINER_URL) && {container: process.env.CONTAINER_URL})
};

const agent = await initAgent(params);

return {
...params,
agent
};
};
65 changes: 49 additions & 16 deletions src/api/agent.api.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,56 @@
import {HttpAgent} from '@dfinity/agent';
import {nonNullish} from '@junobuild/utils';
import type {ActorParameters} from '@junobuild/admin';
import {isNullish, nonNullish} from '@junobuild/utils';
import {REVOKED_CONTROLLERS} from '../constants/constants';
import {actorParameters} from './actor.api';

export const initAgent = async (): Promise<HttpAgent> => {
const {identity, container, fetch} = await actorParameters();
export class AgentApi {
#agents: Record<string, HttpAgent> | undefined = undefined;

const localActor = nonNullish(container) && container !== false;
async getAgent({identity, ...rest}: Omit<ActorParameters, 'agent'>): Promise<HttpAgent> {
const key = identity.getPrincipal().toText();

const host = localActor
? container === true
? 'http://127.0.0.1:5987'
: container
: 'https://icp-api.io';
if (isNullish(this.#agents) || isNullish(this.#agents[key])) {
const agent = await this.createAgent({identity, ...rest});

return await HttpAgent.create({
identity,
host,
retryTimes: 10,
fetch,
shouldFetchRootKey: localActor
});
this.#agents = {
...(this.#agents ?? {}),
[key]: agent
};

return agent;
}

return this.#agents[key];
}

private async createAgent({identity, container, fetch}: ActorParameters): Promise<HttpAgent> {
const localActor = nonNullish(container) && container !== false;

const host = localActor
? container === true
? 'http://127.0.0.1:5987'
: container
: 'https://icp-api.io';

return await HttpAgent.create({
identity,
host,
retryTimes: 10,
fetch,
shouldFetchRootKey: localActor
});
}
}

const agent = new AgentApi();

export const initAgent = async (params?: Omit<ActorParameters, 'agent'>): Promise<HttpAgent> => {
const {identity, ...rest} = params ?? (await actorParameters());

if (REVOKED_CONTROLLERS.includes(identity.getPrincipal().toText())) {
throw new Error('The controller has been revoked for security reason!');
}

return await agent.getAgent({identity, ...rest});
};