Since I’m going to implement important functionality related to cycles, I’ll have to give up subnet_type="system"
and a very convenient set of nns canisters. Directly from the application I use 3 types of canisters - ledger
, cmc
and internet identity
. I replaced the lines in my deploy.sh
script
dfx extension install nns
dfx nns install
with
source ./scripts/ledger.sh
source ./scripts/cmc.sh
ledger.sh
#!/usr/bin/env bash
SRC_DIR="src/backend/ledger"
# Install ledger locally as documented in:
# https://internetcomputer.org/docs/current/developer-docs/integrations/ledger/ledger-local-setup
IC_VERSION=a17247bd86c7aa4e87742bf74d108614580f216d
mkdir -p $SRC_DIR
curl -kLo $SRC_DIR/ledger.wasm.gz https://download.dfinity.systems/ic/$IC_VERSION/canisters/ledger-canister.wasm.gzhttps://raw.githubusercontent.com/dfinity/ic/$IC_VERSION/rs/rosetta-api/ledger.did
curl -kLo $SRC_DIR/ledger.did https://raw.githubusercontent.com/dfinity/ic/$IC_VERSION/rs/rosetta-api/icp_ledger/ledger.did
mkdir .dfx/local/canisters/ledger
cp $SRC_DIR/ledger.wasm.gz .dfx/local/canisters/ledger/ledger.wasm.gz
dfx identity new --storage-mode=plaintext minter
dfx identity use minter
MINT_ACC=$(dfx identity get-principal)
dfx identity use default
ARCHIVE_CONTROLLER=$(dfx identity get-principal)
LEDGER_ACC=$(dfx identity get-principal)
ACCOUNT_ID=$(dfx ledger account-id)
dfx deploy ledger --specified-id ryjl3-tyaaa-aaaaa-aaaba-cai --argument "(variant {
Init = record {
send_whitelist = vec {
principal \"$LEDGER_ACC\";
};
token_symbol = opt \"ICP\";
transfer_fee = opt record { e8s = 10000 : nat64 };
minting_account = \"$ACCOUNT_ID\";
transaction_window = opt record {
secs = 10 : nat64;
nanos = 0 : nat32;
};
max_message_size_bytes = opt(2560000 : nat64);
icrc1_minting_account = opt record {
owner = principal \"$MINT_ACC\";
subaccount = null;
};
archive_options = opt record {
num_blocks_to_archive = 1000000 : nat64;
max_transactions_per_response = null;
trigger_threshold = 1000000 : nat64;
max_message_size_bytes = null;
cycles_for_archive_creation = null;
node_max_memory_size_bytes = null;
controller_id = principal \"$ARCHIVE_CONTROLLER\";
};
initial_values = vec {
record {
\"$ACCOUNT_ID\";
record {
e8s = 10000000000 : nat64;
};
};
};
token_name = opt \"Internet Computer\";
}
})" --yes -qq --upgrade-unchanged
cmc.sh
#!/usr/bin/env bash
SRC_DIR="src/backend/cmc"
IC_VERSION=a17247bd86c7aa4e87742bf74d108614580f216d
mkdir -p $SRC_DIR
curl -kLo $SRC_DIR/cmc.wasm.gz https://download.dfinity.systems/ic/$IC_VERSION/canisters/cycles-minting-canister.wasm.gz
mkdir .dfx/local/canisters/cmc
cp $SRC_DIR/cmc.wasm .dfx/local/canisters/cmc/cmc.wasm.gz
curl -kLo $SRC_DIR/cmc.did https://raw.githubusercontent.com/dfinity/ic/$IC_VERSION/rs/nns/cmc/cmc.did
didc bind $SRC_DIR/cmc.did -t mo > $SRC_DIR/cmc.mo
dfx identity new --storage-mode=plaintext minter
dfx identity use minter
MINT_ACC=$(dfx identity get-principal)
MINT_ACC_ID=$(node ./scripts/ledger.account-id.mjs --to did --principal $MINT_ACC)
# MINT_ACC_ID=record { bytes = vec { ... } };
dfx identity use default
LEDGER_ID=$(dfx canister id ledger)
dfx deploy cmc --specified-id rkp4c-7iaaa-aaaaa-aaaca-cai --argument "(opt record {
minting_account_id = opt ${MINT_ACC_ID};
ledger_canister_id = opt principal \"${LEDGER_ID}\";
governance_canister_id = opt principal \"aaaaa-aa\";
last_purged_notification = opt 0;
exchange_rate_canister = null;
})" --yes -qq --upgrade-unchanged
dfx.json canisters section
"ledger": {
"type": "custom",
"candid": "src/backend/ledger/ledger.did",
"wasm": "src/backend/ledger/ledger.wasm.gz",
"remote": {
"id": {
"ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
}
},
"declarations": {
"node_compatibility": true
}
},
"cmc": {
"type": "custom",
"candid": "src/backend/cmc/cmc.did",
"wasm": "src/backend/cmc/cmc.wasm.gz",
"remote": {
"id": {
"ic": "rkp4c-7iaaa-aaaaa-aaaca-cai"
}
},
"declarations": {
"node_compatibility": true
}
}
Ledger seems to work correctly at first glance, I initialize it with 100 ICP on balance. In an actor I’m trying to create a canister
let result = await Ledger.transfer({
to = account;
fee = { e8s = FEE };
memo = MEMO_CREATE_CANISTER;
from_subaccount = ?fromSubaccount;
amount;
created_at_time = ?{ timestamp_nanos = Nat64.fromNat(Int.abs(Time.now())) };
});
and after that I notify CMC
let notifyResult = await CMC.notify_create_canister({ block_index = height; controller = self; subnet_type = null });
And at this step I get an error
Refunded({block_index = ?3; reason = "No subnets in which to create a canister."})
@Severin what am I doing wrong? How to create a subnet?