Skip to content

Commit 624664d

Browse files
feat: CMC post-install to authorize to create canisters in subnet (#43)
* feat: CMC post-install to authorize to create canisters in subnet * feat: neuronId constant was moved * fix: nullish * fix: principal self authenticating
1 parent baa8c28 commit 624664d

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {IDL} from '@dfinity/candid';
2+
import {GovernanceCanister, NnsFunction, type MakeProposalRequest} from '@dfinity/nns';
3+
import {Principal} from '@dfinity/principal';
4+
import {arrayBufferToUint8Array, createAgent} from '@dfinity/utils';
5+
import {MAIN_IDENTITY_KEY} from '../../constants/constants';
6+
import {NEURON_ID} from '../../constants/modules.constants';
7+
import type {ModuleInstallParams} from '../../types/module';
8+
9+
export const makeAuthorizedSubnetworksProposal = async ({
10+
identities
11+
}: Pick<ModuleInstallParams, 'identities'>) => {
12+
const {[MAIN_IDENTITY_KEY]: identity} = identities;
13+
14+
const agent = await createAgent({
15+
identity,
16+
host: 'http://127.0.0.1:5987',
17+
fetchRootKey: true
18+
});
19+
20+
const {makeProposal} = GovernanceCanister.create({
21+
agent
22+
});
23+
24+
const subnetId = Principal.selfAuthenticating(arrayBufferToUint8Array(agent.rootKey));
25+
26+
const arg = IDL.encode(
27+
[
28+
IDL.Record({
29+
who: IDL.Opt(IDL.Principal),
30+
subnets: IDL.Vec(IDL.Principal)
31+
})
32+
],
33+
[
34+
{
35+
who: [],
36+
subnets: [subnetId]
37+
}
38+
]
39+
);
40+
41+
const request: MakeProposalRequest = {
42+
neuronId: BigInt(NEURON_ID),
43+
url: 'https://forum.dfinity.org',
44+
title: 'Authorize CMC to create canisters in subnets',
45+
summary: 'The lack of documentation makes developing anything with the CMC canister a pain.',
46+
action: {
47+
ExecuteNnsFunction: {
48+
nnsFunctionId: NnsFunction.SetAuthorizedSubnetworks,
49+
payloadBytes: arg
50+
}
51+
}
52+
};
53+
54+
await makeProposal(request);
55+
};

cli/src/modules/cmc/index.ts

+22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
import {assertNonNullish} from '@dfinity/utils';
2+
import kleur from 'kleur';
13
import {Module} from '../../services/modules.services';
24
import type {ModuleDescription, ModuleInstallParams} from '../../types/module';
35
import {prepareCmcArgs} from './cmc.install';
6+
import {makeAuthorizedSubnetworksProposal} from './cmc.post-install';
7+
8+
const {green, cyan} = kleur;
49

510
const CMC: ModuleDescription = {
611
key: 'cmc',
@@ -19,6 +24,23 @@ class CmcModule extends Module {
1924
...rest
2025
});
2126
}
27+
28+
override async postInstall(context: ModuleInstallParams): Promise<void> {
29+
await makeAuthorizedSubnetworksProposal(context);
30+
31+
const {state} = context;
32+
33+
const metadata = state.getModule(this.key);
34+
35+
assertNonNullish(
36+
metadata,
37+
'Module has not been installed and therefore cannot be post-installed!'
38+
);
39+
40+
const {name, canisterId} = metadata;
41+
42+
console.log(`🫠 ${green(name)} post-install. ID: ${cyan(canisterId.toString())}`);
43+
}
2244
}
2345

2446
export const cmc = new CmcModule(CMC);

0 commit comments

Comments
 (0)