I’m so sorry for that confusion. That download icp ledger script for some other purpose. It’s not included in the issue I’m facing right now. The ICRC ledger suite is what I’m deploying now.
Basically, with the help of create canister, we’re making the user launch their own token, and it’s respective index canister. The only issue I’m facing is, I can’t use any endpoints of index canister except the ledger id endpoint- which returns me the perfect icrc ledger canister id, but the rest are null.
I believe the code below can help you with some context:
async fn create_canister(
arg: CreateCanisterArgument, // cycles: u128,
) → CallResult<(CanisterIdRecord,)> {
let extended_arg = CreateCanisterArgumentExtended {
settings: arg.settings,
sender_canister_version: Some(canister_version()),
};
let cycles: u128 = 100_000_000_000;
call_with_payment128(
Principal::management_canister(),
"create_canister",
(extended_arg,),
cycles,
)
.await
}
async fn deposit_cycles(arg: CanisterIdRecord, cycles: u128) → CallResult<()> {
call_with_payment128(
Principal::management_canister(),
“deposit_cycles”,
(arg,),
cycles,
)
.await
}
async fn install_code(arg: InstallCodeArgument, wasm_module: Vec) → CallResult<()> {
let cycles: u128 = 10_000_000_000;
let extended_arg = InstallCodeArgumentExtended {
mode: arg.mode,
canister_id: arg.canister_id,
wasm_module: WasmModule::from(wasm_module),
arg: arg.arg,
sender_canister_version: Some(canister_version()),
};
call_with_payment128(
Principal::management_canister(),
"install_code",
(extended_arg,),
cycles,
)
.await
}
async fn index_install_code(arg: IndexInstallCodeArgument, wasm_module: Vec) → CallResult<()> {
let cycles: u128 = 10_000_000_000;
let extended_arg = IndexInstallCodeArgumentExtended {
mode: arg.mode,
arg: arg.arg,
canister_id: arg.canister_id,
wasm_module: WasmModule::from(wasm_module),
sender_canister_version: Some(canister_version()),
};
call_with_payment128(
Principal::management_canister(),
"install_code",
(extended_arg,),
cycles,
)
.await
}
#[derive(CandidType, Deserialize, Serialize, Debug)]
pub struct TokenCreationResult {
pub ledger_canister_id: Principal,
pub index_canister_id: Principal,
}
#[ic_cdk::update]
pub async fn create_token(user_params: UserInputParams) → Result<TokenCreationResult, String> {
let arg = CreateCanisterArgument { settings: None };
// Create ledger canister
let (canister_id,) = match create_canister(arg.clone()).await {
Ok(id) => id,
Err((_, err_string)) => {
ic_cdk::println!("error in canister id");
return Err(format!("Error: {}", err_string));
}
};
// Create index canister
let (index_canister_id,) = match create_canister(arg.clone()).await {
Ok(id) => id,
Err((_, err_string)) => {
ic_cdk::println!("error in canister id");
return Err(format!("Error: {}", err_string));
}
};
let _addcycles = deposit_cycles(canister_id, 150_000_000_000).await.unwrap();
let _addcycles_index = deposit_cycles(index_canister_id, 100_000_000_000).await.unwrap();
let canister_id_principal = canister_id.canister_id;
let index_canister_id_principal = index_canister_id.canister_id;
let minting_account = params::MINTING_ACCOUNT.lock().unwrap().clone().map_err(|e| e.to_string())?;
// Handle potential error from FEE_COLLECTOR_ACCOUNT
let fee_collector_account = params::FEE_COLLECTOR_ACCOUNT.lock().unwrap().clone().map_err(|e| e.to_string())?;
// Handle potential error from ARCHIVE_OPTIONS
let archive_options = params::ARCHIVE_OPTIONS.lock().unwrap().clone().map_err(|e| e.to_string())?;
// Ledger Init Args
let init_args = LedgerArg::Init(InitArgs {
minting_account, // Hardcoded value from params.rs
fee_collector_account: Some(fee_collector_account), // Hardcoded value from params.rs
transfer_fee: params::TRANSFER_FEE.clone(), // Hardcoded value
decimals: user_params.decimals, // User-supplied value
max_memo_length: Some(params::MAX_MEMO_LENGTH), // Hardcoded value
token_symbol: user_params.token_symbol.clone(), // User-supplied value
token_name: user_params.token_name.clone(), // User-supplied value
metadata: vec![], // Empty or pre-defined metadata if needed
initial_balances: user_params.initial_balances, // User-supplied value
feature_flags: Some(params::FEATURE_FLAGS), // Hardcoded value
maximum_number_of_accounts: Some(params::MAXIMUM_NUMBER_OF_ACCOUNTS), // Hardcoded value
accounts_overflow_trim_quantity: Some(params::ACCOUNTS_OVERFLOW_TRIM_QUANTITY), // Hardcoded value
archive_options, // Hardcoded value from params.rs
});
let init_arg: Vec<u8> = encode_one(init_args).map_err(|e| e.to_string())?;
let wasm_module =
include_bytes!("../../../.dfx/local/canisters/token_deployer/token_deployer.wasm.gz")
.to_vec();
let index_wasm_module =
include_bytes!("../../../.dfx/local/canisters/index_canister/index_canister.wasm.gz")
.to_vec();
let arg1: InstallCodeArgument = InstallCodeArgument {
mode: CanisterInstallMode::Install,
canister_id: canister_id_principal,
wasm_module: WasmModule::from(wasm_module.clone()),
arg: init_arg.clone(),
};
// Index Init Args
let index_init_args = IndexInitArgs {
ledger_id: canister_id_principal,
};
let index_init_arg: Vec<u8> = encode_one(index_init_args).map_err(|e| e.to_string())?;
let arg2: IndexInstallCodeArgument = IndexInstallCodeArgument {
mode: CanisterInstallMode::Install,
canister_id: index_canister_id_principal,
wasm_module: WasmModule::from(index_wasm_module.clone()),
arg: index_init_arg,
};
// Install code for the ledger canister
match install_code(arg1.clone(), wasm_module).await {
Ok(_) => {
mutate_state(|state| {
state.canister_ids.insert(canister_id_principal.to_string(), CanisterIdWrapper {
canister_ids: canister_id_principal,
token_name: user_params.token_name.clone(), // Store token name
token_symbol: user_params.token_symbol.clone(), // Store token symbol
image_id: None, // Set image_id as None for now
ledger_id: Some(canister_id_principal), // Set ledger_id to the canister ID
});
});
}
Err((code, msg)) => {
ic_cdk::println!("Error installing code: {} - {}", code as u8, msg);
return Err(format!("Error installing code: {} - {}", code as u8, msg));
}
}
// Install code for the index canister
match index_install_code(arg2, index_wasm_module).await {
Ok(_) => {
mutate_state(|state| {
state.index_canister_ids.insert(
index_canister_id_principal.to_string(),
IndexCanisterIdWrapper {
index_canister_ids: index_canister_id_principal,
},
)
});
Ok(TokenCreationResult {
ledger_canister_id: canister_id_principal,
index_canister_id: index_canister_id_principal,
})
}
Err((code, msg)) => {
Err(format!("Error installing index code: {} - {}", code as u8, msg))
}
}
}