diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bca6227be0..6eec6ff8d9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -214,7 +214,7 @@ jobs: env: ETHEREUM_URL: ${{ secrets.ETHEREUM_URL }} AZLE_USE_DOCKERFILE: ${{ matrix.azle_source == 'repo' }} - AZLE_PLAINTEXT_IDENTITY: true + AZLE_PLAINTEXT_IDENTITY: 'plaintext' strategy: fail-fast: false # We want to see which example tests succeed and which ones fail, we don't want one example test to cancel the rest matrix: diff --git a/dfx/index.ts b/dfx/index.ts index 710d19bf2b..ec46251525 100644 --- a/dfx/index.ts +++ b/dfx/index.ts @@ -1,8 +1,5 @@ import { execSync } from 'child_process'; import { Secp256k1KeyIdentity } from '@dfinity/identity-secp256k1'; -import { readFile } from 'fs/promises'; -import { homedir } from 'os'; -import { join } from 'path'; import { HttpAgent } from '@dfinity/agent'; export function getCanisterId(canisterName: string): string { @@ -42,11 +39,11 @@ export async function createAnonymousAgent() { } export async function createAuthenticatedAgent( - identityName?: string + identityName: string ): Promise { const agent = new HttpAgent({ host: getAgentHost(), - identity: getIdentity(identityName) + identity: getSecp256k1KeyIdentity(identityName) }); if (process.env.DFX_NETWORK !== 'ic') { @@ -56,24 +53,21 @@ export async function createAuthenticatedAgent( return agent; } -export function getIdentityName(): string { +export function whoami(): string { return execSync(`dfx identity whoami`).toString().trim(); } type StorageMode = 'keyring' | 'password-protected' | 'plaintext'; -export function generateIdentity( - name: string, - storageModeCool?: StorageMode -): Buffer { +export function generateIdentity(name: string): Buffer { console.info(); console.info(`Generating identity ${name}`); - const storageMode = determineStorageMode(storageModeCool); + const storageMode = determineStorageMode(); if (storageMode === undefined) { console.info(`You may be prompted to create a password for ${name}`); console.info(); return execSync(`dfx identity new ${name}`, { - stdio: ['inherit', 'pipe', 'inherit'] + stdio: ['inherit', 'pipe', 'inherit'] // TODO I would prefer it to pipe the stderr but pipe will cause this command to fail immediately }); } if (storageMode === 'password-protected') { @@ -81,17 +75,23 @@ export function generateIdentity( console.info(); } return execSync(`dfx identity new ${name} --storage-mode ${storageMode}`, { - stdio: ['inherit', 'pipe', 'inherit'] // TODO add todo here and aboe + stdio: ['inherit', 'pipe', 'inherit'] // TODO I would prefer it to pipe the stderr but pipe will cause this command to fail immediately }); } -function determineStorageMode( - storageMode?: StorageMode -): StorageMode | undefined { - if (process.env.AZLE_PLAINTEXT_IDENTITY === 'true') { - return 'plaintext'; +function determineStorageMode(): StorageMode | undefined { + const mode = process.env.AZLE_IDENTITY_STORAGE_MODE; + if ( + mode !== 'plaintext' && + mode !== 'keyring' && + mode !== 'password-protected' && + mode !== undefined + ) { + throw new Error( + `AZLE_IDENTITY_STORAGE_MODE must be 'plaintext', 'keyring', 'password-protected', or undefined` + ); } - return storageMode; + return mode; } export function useIdentity(name: string) { @@ -114,46 +114,34 @@ export function removeIdentity(name: string) { execSync(`dfx identity remove ${name}`); } -export async function getIdentityFromPemFile( - identityName: string = getIdentityName() -): Promise { - const identityPath = join( - homedir(), - '.config', - 'dfx', - 'identity', - identityName, - 'identity.pem' - ); - return Secp256k1KeyIdentity.fromPem(await readFile(identityPath, 'utf-8')); -} - -export function getPemKey(identityName: string = getIdentityName()): string { +export function getPemKey(identityName: string): string { console.info(); console.info(`Exporting PEM key for ${identityName}`); console.info(`You may be prompted for ${identityName}'s password`); console.info(); const cmd = `dfx identity export ${identityName}`; const result = execSync(cmd, { - stdio: ['inherit', 'pipe', 'inherit'] // TODO I would prefer it to pipe the stderr but it will fail immediately if you do that + stdio: ['inherit', 'pipe', 'inherit'] // TODO I would prefer it to pipe the stderr but pipe will cause this command to fail immediately }) .toString() .trim(); return result; } -export function getIdentity(identityName?: string): Secp256k1KeyIdentity { +export function getSecp256k1KeyIdentity( + identityName: string +): Secp256k1KeyIdentity { return Secp256k1KeyIdentity.fromPem(getPemKey(identityName)); } -export function getPrincipal(identityName: string = getIdentityName()): string { +export function getPrincipal(identityName: string = whoami()): string { console.info(); console.info(`Getting principal for ${identityName}`); console.info(`You may be prompted for ${identityName}'s password`); console.info(); const cmd = `dfx identity get-principal --identity ${identityName}`; return execSync(cmd, { - stdio: ['inherit', 'pipe', 'inherit'] // TODO add todo + stdio: ['inherit', 'pipe', 'inherit'] // TODO I would prefer it to pipe the stderr but pipe will cause this command to fail immediately }) .toString() .trim(); @@ -164,11 +152,11 @@ export function addController( identityName: string, principal: string ) { - const currentIdentity = getIdentityName(); + const currentIdentity = whoami(); console.info(); console.info(`Adding ${identityName} as a controller for ${canisterName}`); console.info(`You may be prompted for ${currentIdentity}'s password`); console.info(); const cmd = `dfx canister update-settings ${canisterName} --add-controller ${principal}`; - return execSync(cmd, { stdio: ['inherit', 'pipe', 'inherit'] }); // TODO I would prefer it to pipe the stderr but it will fail immediately if you do that + return execSync(cmd, { stdio: ['inherit', 'pipe', 'inherit'] }); // TODO I would prefer it to pipe the stderr but pipe will cause this command to fail immediately } diff --git a/examples/large_files/test/tests.ts b/examples/large_files/test/tests.ts index a61e64bb80..c82cbbc4bd 100644 --- a/examples/large_files/test/tests.ts +++ b/examples/large_files/test/tests.ts @@ -10,6 +10,7 @@ import { rm } from 'fs/promises'; import { generateTestFileOfSize } from './generateTestFiles'; import { createActor } from 'azle/src/compiler/file_uploader/uploader_actor'; import { v4 } from 'uuid'; +import { AZLE_UPLOADER_IDENTITY_NAME } from '../../../src/compiler/file_uploader/uploader_identity'; export function getTests(canisterId: string): Test[] { const origin = `http://${canisterId}.localhost:8000`; @@ -228,7 +229,10 @@ function generateTest( }; } - const actor = await createActor(getCanisterId('backend')); + const actor = await createActor( + getCanisterId('backend'), + AZLE_UPLOADER_IDENTITY_NAME + ); const hash = await actor.get_file_hash(canisterFilePath); if (hash.length === 1) { diff --git a/src/compiler/file_uploader/uploader_actor.ts b/src/compiler/file_uploader/uploader_actor.ts index 91d237fdfb..65db1b8885 100644 --- a/src/compiler/file_uploader/uploader_actor.ts +++ b/src/compiler/file_uploader/uploader_actor.ts @@ -1,12 +1,11 @@ import { Actor, ActorMethod, ActorSubclass } from '@dfinity/agent'; import { createAuthenticatedAgent } from '../../../dfx'; -import { AZLE_UPLOADER_IDENTITY_NAME } from './uploader_identity'; export type UploaderActor = ActorSubclass<_SERVICE>; export async function createActor( canisterId: string, - identityName: string = AZLE_UPLOADER_IDENTITY_NAME + identityName: string ): Promise { const agent = await createAuthenticatedAgent(identityName); diff --git a/src/compiler/file_uploader/uploader_identity.ts b/src/compiler/file_uploader/uploader_identity.ts index 6b32c930a6..c35f0190d5 100644 --- a/src/compiler/file_uploader/uploader_identity.ts +++ b/src/compiler/file_uploader/uploader_identity.ts @@ -5,7 +5,8 @@ import { identityExists } from '../../../dfx'; -export const AZLE_UPLOADER_IDENTITY_NAME = '_azle_file_uploader_identity'; +export const AZLE_UPLOADER_IDENTITY_NAME = + process.env.AZLE_UPLOADER_IDENTITY_NAME || '_azle_file_uploader_identity'; export function generateUploaderIdentity(canisterName: string): string { if (!identityExists(AZLE_UPLOADER_IDENTITY_NAME)) { diff --git a/src/compiler/file_watcher/file_watcher.ts b/src/compiler/file_watcher/file_watcher.ts index 48de44e4a0..a12d5d3f95 100644 --- a/src/compiler/file_watcher/file_watcher.ts +++ b/src/compiler/file_watcher/file_watcher.ts @@ -1,16 +1,15 @@ -import { Actor, HttpAgent } from '@dfinity/agent'; +import { Actor } from '@dfinity/agent'; import { watch } from 'chokidar'; import { readFileSync, writeFileSync } from 'fs'; import { getCanisterJavaScript } from '../get_canister_javascript'; import { ok } from '../utils/result'; -import { createAuthenticatedAgent } from '../../../dfx'; +import { createAuthenticatedAgent, whoami } from '../../../dfx'; const reloadedJsPath = process.argv[2]; const canisterId = process.argv[3]; const mainPath = process.argv[4]; const wasmedgeQuickJsPath = process.argv[5]; -const replicaWebServerPort = process.argv[6]; // TODO https://github.com/demergent-labs/azle/issues/1664 watch(process.cwd(), { @@ -27,8 +26,7 @@ watch(process.cwd(), { reloadedJsPath, canisterId, mainPath, - wasmedgeQuickJsPath, - replicaWebServerPort + wasmedgeQuickJsPath ); } catch (error) { console.error(error); @@ -40,8 +38,7 @@ async function reloadJs( reloadedJsPath: string, canisterId: string, mainPath: string, - wasmedgeQuickJsPath: string, - replicaWebServerPort: string + wasmedgeQuickJsPath: string ) { const canisterJavaScriptResult = getCanisterJavaScript( mainPath, @@ -60,7 +57,7 @@ async function reloadJs( writeFileSync(reloadedJsPath, canisterJavaScriptResult.ok); - const agent = await createAuthenticatedAgent(); + const agent = await createAuthenticatedAgent(whoami()); const actor = Actor.createActor( ({ IDL }) => {