Skip to content

Commit

Permalink
feat(frontend,devOps): Split backend (#2043)
Browse files Browse the repository at this point in the history
# Motivation
Here we wish to make the frontend make all its signing API calls to the
signing canister.

# Changes
- Create a signing agent.
- Move all signing API calls from the backend agent to the signer agent.

# Tests
- Existing CI should pass.
  • Loading branch information
bitdivine authored Aug 20, 2024
1 parent 4cbb5bd commit 71576cc
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/frontend/src/eth/services/send.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
toCkErc20HelperContractAddress,
toCkEthHelperContractAddress
} from '$icp-eth/utils/cketh.utils';
import { signTransaction } from '$lib/api/backend.api';
import { signTransaction } from '$lib/api/signer.api';
import { DEFAULT_ETHEREUM_NETWORK } from '$lib/constants/networks.constants';
import { ProgressStepsSend } from '$lib/enums/progress-steps';
import { i18n } from '$lib/stores/i18n.store';
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/eth/services/wallet-connect.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
getSignParamsMessageTypedDataV4Hash
} from '$eth/utils/wallet-connect.utils';
import { assertCkEthMinterInfoLoaded } from '$icp-eth/services/cketh.services';
import { signMessage as signMessageApi, signPrehash } from '$lib/api/backend.api';
import { signMessage as signMessageApi, signPrehash } from '$lib/api/signer.api';
import {
TRACK_COUNT_WC_ETH_SEND_ERROR,
TRACK_COUNT_WC_ETH_SEND_SUCCESS,
Expand Down
37 changes: 35 additions & 2 deletions src/frontend/src/lib/actors/actors.ic.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { _SERVICE as BackendActor } from '$declarations/backend/backend.did';
import { idlFactory as idlCertifiedFactoryBackend } from '$declarations/backend/backend.factory.certified.did';
import { idlFactory as idlFactoryBackend } from '$declarations/backend/backend.factory.did';
import { BACKEND_CANISTER_ID } from '$lib/constants/app.constants';
import type { _SERVICE as SignerActor } from '$declarations/signer/signer.did';
import { idlFactory as idlCertifiedFactorySigner } from '$declarations/signer/signer.factory.certified.did';
import { idlFactory as idlFactorySigner } from '$declarations/signer/signer.factory.did';
import { BACKEND_CANISTER_ID, SIGNER_CANISTER_ID } from '$lib/constants/app.constants';
import { i18n } from '$lib/stores/i18n.store';
import type { OptionIdentity } from '$lib/types/identity';
import { Actor, type ActorMethod, type ActorSubclass, type Identity } from '@dfinity/agent';
Expand All @@ -11,7 +14,7 @@ import { assertNonNullish, isNullish } from '@dfinity/utils';
import { get } from 'svelte/store';
import { getAgent } from './agents.ic';

let actors: { backend?: BackendActor } | undefined | null = undefined;
let actors: { backend?: BackendActor; signer?: SignerActor } | undefined | null = undefined;

export const getBackendActor = async ({
identity,
Expand Down Expand Up @@ -42,6 +45,36 @@ export const getBackendActor = async ({
return backend;
};

export const getSignerActor = async ({
identity,
certified = true
}: {
identity: OptionIdentity;
certified?: boolean;
}): Promise<SignerActor> => {
// TODO: Delete this dependency once the signer has been stripped down.
assertNonNullish(identity, get(i18n).auth.error.no_internet_identity);

const { signer } = actors ?? { signer: undefined };

if (isNullish(signer)) {
const actor = await createActor<SignerActor>({
canisterId: SIGNER_CANISTER_ID,
idlFactory: certified ? idlCertifiedFactorySigner : idlFactorySigner,
identity
});

actors = {
...(actors ?? {}),
signer: actor
};

return actor;
}

return signer;
};

export const clearActors = () => (actors = null);

const createActor = async <T = Record<string, ActorMethod>>({
Expand Down
52 changes: 0 additions & 52 deletions src/frontend/src/lib/api/backend.api.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,17 @@
import type {
AddUserCredentialError,
BitcoinNetwork,
CredentialSpec,
CustomToken,
GetUserProfileError,
SignRequest,
UserProfile,
UserToken
} from '$declarations/backend/backend.did';
import { getBackendActor } from '$lib/actors/actors.ic';
import type { EthAddress } from '$lib/types/address';
import type { OptionIdentity } from '$lib/types/identity';
import type { Identity } from '@dfinity/agent';
import type { Principal } from '@dfinity/principal';
import { toNullable, type QueryParams } from '@dfinity/utils';

export const getBtcAddress = async ({
identity,
network
}: {
identity: OptionIdentity;
network: BitcoinNetwork;
}): Promise<EthAddress> => {
const { caller_btc_address } = await getBackendActor({ identity });
return caller_btc_address(network);
};

export const getEthAddress = async (identity: OptionIdentity): Promise<EthAddress> => {
const { caller_eth_address } = await getBackendActor({ identity });
return caller_eth_address();
};

export const signTransaction = async ({
transaction,
identity
}: {
transaction: SignRequest;
identity: OptionIdentity;
}): Promise<string> => {
const { sign_transaction } = await getBackendActor({ identity });
return sign_transaction(transaction);
};

export const signMessage = async ({
message,
identity
}: {
message: string;
identity: OptionIdentity;
}): Promise<string> => {
const { personal_sign } = await getBackendActor({ identity });
return personal_sign(message);
};

export const signPrehash = async ({
hash,
identity
}: {
hash: string;
identity: OptionIdentity;
}): Promise<string> => {
const { sign_prehash } = await getBackendActor({ identity });
return sign_prehash(hash);
};

export const listUserTokens = async ({
identity,
certified = true
Expand Down
53 changes: 53 additions & 0 deletions src/frontend/src/lib/api/signer.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { BitcoinNetwork, SignRequest } from '$declarations/signer/signer.did';
import { getBackendActor } from '$lib/actors/actors.ic';
import type { EthAddress } from '$lib/types/address';
import type { OptionIdentity } from '$lib/types/identity';

export const getBtcAddress = async ({
identity,
network
}: {
identity: OptionIdentity;
network: BitcoinNetwork;
}): Promise<EthAddress> => {
const { caller_btc_address } = await getBackendActor({ identity });
return caller_btc_address(network);
};

export const getEthAddress = async (identity: OptionIdentity): Promise<EthAddress> => {
const { caller_eth_address } = await getBackendActor({ identity });
return caller_eth_address();
};

export const signTransaction = async ({
transaction,
identity
}: {
transaction: SignRequest;
identity: OptionIdentity;
}): Promise<string> => {
const { sign_transaction } = await getBackendActor({ identity });
return sign_transaction(transaction);
};

export const signMessage = async ({
message,
identity
}: {
message: string;
identity: OptionIdentity;
}): Promise<string> => {
const { personal_sign } = await getBackendActor({ identity });
return personal_sign(message);
};

export const signPrehash = async ({
hash,
identity
}: {
hash: string;
identity: OptionIdentity;
}): Promise<string> => {
const { sign_prehash } = await getBackendActor({ identity });
return sign_prehash(hash);
};
6 changes: 6 additions & 0 deletions src/frontend/src/lib/constants/app.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export const BACKEND_CANISTER_ID = LOCAL
? import.meta.env.VITE_STAGING_BACKEND_CANISTER_ID
: import.meta.env.VITE_IC_BACKEND_CANISTER_ID;

export const SIGNER_CANISTER_ID = LOCAL
? import.meta.env.VITE_LOCAL_SIGNER_CANISTER_ID
: STAGING
? import.meta.env.VITE_STAGING_SIGNER_CANISTER_ID
: import.meta.env.VITE_IC_SIGNER_CANISTER_ID;

// How long the delegation identity should remain valid?
// e.g. BigInt(60 * 60 * 1000 * 1000 * 1000) = 1 hour in nanoseconds
export const AUTH_MAX_TIME_TO_LIVE = BigInt(60 * 60 * 1000 * 1000 * 1000);
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/lib/services/address.services.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BTC_MAINNET_TOKEN_ID } from '$env/tokens.btc.env';
import { ETHEREUM_TOKEN_ID } from '$env/tokens.env';
import { getBtcAddress, getEthAddress } from '$lib/api/backend.api';
import {
getIdbBtcAddressMainnet,
getIdbEthAddress,
Expand All @@ -9,6 +8,7 @@ import {
updateIdbBtcAddressMainnetLastUsage,
updateIdbEthAddressLastUsage
} from '$lib/api/idb.api';
import { getBtcAddress, getEthAddress } from '$lib/api/signer.api';
import { addressStore } from '$lib/stores/address.store';
import { authStore } from '$lib/stores/auth.store';
import { i18n } from '$lib/stores/i18n.store';
Expand Down

0 comments on commit 71576cc

Please sign in to comment.