# How to deploy the ICP Ledger locally?

**URL:** <https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183>\
**Category:** Developers\
**Created:** [May 22, 2021, 4:15pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183 "2021-05-22T16:15:21Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dpdp](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dpdp/32/1143_2.png) [@dpdp](https://forum.dfinity.org/u/dpdp)\
**Post date:** [May 22, 2021, 4:15pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/1 "2021-05-22T16:15:21Z")

</div>

I have been trying to deploy the ICP Ledger locally; But it seems I might do something wrong.

Reproduce step:  
dfx.json

```auto
    "ledger": {
      "type": "custom",
      "candid": "/Users/unknown/nns-ifaces/ledger.did",
      "wasm": "/Users/unknown/ic/rs/rosetta-api/ledger_canister/wasm/ledger-archive-node-canister.wasm",
      "build": ""
    }

```

- nns-ifaces: [GitHub - dfinity/nns-ifaces: Network Nervous System Canister Interfaces](https://github.com/dfinity/nns-ifaces)
- rosetta-api from the official `dfinity/ic` repository

* * *

```auto
# previously executed: dfx canister create ledger
% dfx canister install --argument 'record {minting_account="15a32831331d752b5c4cff5b9351bea8015d90f2c3831c6f3fca9c5287a4dbff"; initial_values=vec {record{"15a32831331d752b5c4cff5b9351bea8015d90f2c3831c6f3fca9c5287a4dbff";record{e8s=1000000000;}}}; max_message_size_bytes=null;transaction_window=null;archive_options=null;send_whitelist=vec{};}' --mode=reinstall ledger
Reinstalling code for canister ledger, with canister_id rkp4c-7iaaa-aaaaa-aaaca-cai
The invocation to the wallet call forward method failed with the error: An error happened during the call: 5: Canister rkp4c-7iaaa-aaaaa-aaaca-cai trapped explicitly: Panicked at 'Deserialization Failed: "Deserialize error: bytes only takes principal or vec nat8"', /Users/lifted/Projects/dfinity/rs/rust_canisters/dfn_core/src/endpoint.rs:50:21

```

I don’t think my argument are wrong (I actually used `didc random` to check how to write `HashMap` in Candid)

---

<div class="post-metadata">

**Author:** ![flyq](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/flyq/32/3637_2.png) [@flyq](https://forum.dfinity.org/u/flyq)\
**Post date:** [May 23, 2021, 1:32am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/2 "2021-05-23T01:32:58Z")

</div>

> [@How to call the canister by dfx using candid file?](https://forum.dfinity.org/t/how-to-call-the-canister-by-dfx-using-candid-file/4022/2):
>
> dfx cannot fetch did files for external canisters. We are adding better support for this. For now, the work around is to put type annotations for all numbers, e.g. amount=record {e8s=110000:nat64}

---

<div class="post-metadata">

**Author:** ![stephenandrews](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/stephenandrews/32/1803_2.png) [@stephenandrews](https://forum.dfinity.org/u/stephenandrews)\
**Post date:** [May 23, 2021, 1:54am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/3 "2021-05-23T01:54:59Z")

</div>

Let me know if you get this working and what you did, so I can give it a jam when I get home. I had asked somewhere else how to launch a local ledger canister was told not possible so happy to see this!

What are you guys working on @flyq @dpdp ? Would be cool to collab where possible.

---

<div class="post-metadata">

**Author:** ![ccyanxyz](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ccyanxyz/32/1025_2.png) [@ccyanxyz](https://forum.dfinity.org/u/ccyanxyz)\
**Post date:** [June 4, 2021, 11:21am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/4 "2021-06-04T11:21:25Z")

</div>

In dfx.json → ledger → wasm, you are using the archive node wasm, you should use the ledger canister wasm.

---

<div class="post-metadata">

**Author:** ![bobbylingus](https://avatars.discourse-cdn.com/v4/letter/b/85e7bf/32.png) [@bobbylingus](https://forum.dfinity.org/u/bobbylingus)\
**Post date:** [November 2, 2022, 9:35pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/5 "2022-11-02T21:35:12Z")

</div>

> **[ic/rs/rosetta-api/icp\_ledger at master · dfinity/ic](https://github.com/dfinity/ic/tree/master/rs/rosetta-api/icp_ledger)**
>
> master/rs/rosetta-api/icp\_ledger

Link in this page on how to deploy locally is broken.

How to deploy locally?

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [November 3, 2022, 7:10am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/6 "2022-11-03T07:10:13Z")

</div>

[This](https://internetcomputer.org/docs/current/developer-docs/integrations/ledger/ledger-local-setup) is the current official guide to installing the ledger locally. I’ll go put in a redirect

---

<div class="post-metadata">

**Author:** ![cryptoschindler](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/cryptoschindler/32/26_2.png) [@cryptoschindler](https://forum.dfinity.org/u/cryptoschindler)\
**Post date:** [November 17, 2022, 11:40am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/7 "2022-11-17T11:40:13Z")

</div>

with dfx `0.12.0` shouldn’t those instructions give a hint in the beginning regarding `dfx nns install` and `dfx nns import`?

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [November 17, 2022, 12:03pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/8 "2022-11-17T12:03:18Z")

</div>

We’re not quite sure what we want to do with `dfx nns install/import` since it’s a maintainability nightmare the way it is right now. But yes, it would make sense to add a note there once it’s a bit more clear what will happen to those commands

---

<div class="post-metadata">

**Author:** ![cryptoschindler](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/cryptoschindler/32/26_2.png) [@cryptoschindler](https://forum.dfinity.org/u/cryptoschindler)\
**Post date:** [November 18, 2022, 4:28pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/9 "2022-11-18T16:28:52Z")

</div>

this doesn’t work for me, i get `404`s for the did files and an `Access Denied` message for the actual Wasm

---

<div class="post-metadata">

**Author:** ![cryptoschindler](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/cryptoschindler/32/26_2.png) [@cryptoschindler](https://forum.dfinity.org/u/cryptoschindler)\
**Post date:** [November 18, 2022, 4:41pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/10 "2022-11-18T16:41:12Z")

</div>

EDIT: no it wasn’t, but the shell script didn’t work for me.  
apparently `ledger-canister` was renamed to `icp-canister`. will make a PR

---

<div class="post-metadata">

**Author:** ![jorgenbuilder](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jorgenbuilder/32/22166_2.png) [@jorgenbuilder](https://forum.dfinity.org/u/jorgenbuilder)\
**Post date:** [December 19, 2022, 8:49pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/11 "2022-12-19T20:49:21Z")

</div>

I hope that we find a way to make these commands work. Being able to trivially deploy an ICP ledger is critical to efficiency for local replica tests. For lack of this feature, several of my past projects have either a) manually mocked an ICP ledger, b) run tests on mainnet. \<3

---

<div class="post-metadata">

**Author:** ![inviscidpixels](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/inviscidpixels/32/9021_2.png) [@inviscidpixels](https://forum.dfinity.org/u/inviscidpixels)\
**Post date:** [December 20, 2022, 1:23pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/12 "2022-12-20T13:23:48Z")

</div>

I don’t know if it is applicable, but if using `dfx nns install` with other canisters, I have to rebuild those other canisters each time after `dfx nns install` is called again or those canister’s won’t compile if importing one of those nns canisters.

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [December 20, 2022, 5:19pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/13 "2022-12-20T17:19:58Z")

</div>

This sounds sort-of expected. `dfx nns install` means that you did a `dfx start --clean`, right? In this case, dfx knows that since the state got wiped, canister IDs are not valid anymore and therefore the canisters should be recompiled. I guess (haven’t tested) if you did `dfx canister install` instead of `deploy` it would bypass that check if you don’t feel like recompiling.

---

<div class="post-metadata">

**Author:** ![inviscidpixels](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/inviscidpixels/32/9021_2.png) [@inviscidpixels](https://forum.dfinity.org/u/inviscidpixels)\
**Post date:** [December 23, 2022, 7:52pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/14 "2022-12-23T19:52:31Z")

</div>

I should have been more clear. If I have a non-nns canister in the project that imports one of the nns-canisters, after rerunning `dfx stop` `dfx start --clean` `dfx nns install` the first time I try to (create,build)/deploy the non-nns canister, it will always fail. If I run deploy again, it will succeed–in other words, I have to run deploy twice in a row in order for it to work.

Specifically I made a bare-bones project where the default backend Motoko canister imports the nns-ledger, the nns-ledger is added as a dependency to that backend Motoko canister in the project’s dfx.json (after `dfx nns import` is run the first time, since it only needs to be run once for the dfx.json to be configured for the nns canisters), to create a script that resets the project’s replica state (rerunning `dfx nns install` and `dfx deploy backend_canister`). It will compile and the backend\_canister can successfully query the balance of an account identifier, but as I said `dfx deploy backend_canister` has to be run twice in a row since it fails to compile the first time around (I’m guessing because the nns-ledger is not deployed as are the non-nns canisters, so it is not linked correctly automatically without attempting to build it first?). Instead of `dfx deploy` the first time, `dfx canister create <canister>` `dfx build <canister>` also produces the same error even before `dfx install <canister>` would be called. I don’t have the error handy, but iirc it’s specifically related to the import of the nns-canister in the backend canister Motoko file (just the standard default import statement that does work the second time `deploy` is run).

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [January 4, 2023, 9:17am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/15 "2023-01-04T09:17:46Z")

</div>

That sounds like a bug. Would you have a repro handy? If I can avoid it, I’d like to not recreate the setup myself.

---

<div class="post-metadata">

**Author:** ![jamesbeadle](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jamesbeadle/32/10110_2.png) [@jamesbeadle](https://forum.dfinity.org/u/jamesbeadle)\
**Post date:** [April 4, 2023, 8:36am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/16 "2023-04-04T08:36:31Z")

</div>

Hi, I have deployed the local ledger following this guide, however when I try to use it in my main.mo via this import:

import Ledger “canister:ledger”;

I get the error:  
file /.dfx/local/lsp/rno2w-sqaaa-aaaaa-aaacq-cai.did uses Candid types without corresponding Motoko type Motoko

If you could help that would be great.

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [April 4, 2023, 9:37am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/17 "2023-04-04T09:37:26Z")

</div>

That’s not enough info for me to fix the problem - can you maybe reduce it down to a specific example?

---

<div class="post-metadata">

**Author:** ![jamesbeadle](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jamesbeadle/32/10110_2.png) [@jamesbeadle](https://forum.dfinity.org/u/jamesbeadle)\
**Post date:** [April 4, 2023, 9:49am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/18 "2023-04-04T09:49:21Z")

</div>

So I followed the instructions for setting up a local ledger canister here:

> **[Ledger Local Setup | Internet Computer](https://internetcomputer.org/docs/current/developer-docs/integrations/ledger/ledger-local-setup)**
>
> If you are working in a local development environment, i.e with a local replica instead of the public Internet Computer, you can't access the ICP ledger. In order to test your application that integrates with the ICP ledger locally, you need to...

If I run the check:

dfx canister call ledger account\_balance ‘(record { account = ‘$(python3 -c ‘print(“vec{” + “;”.join([f"{b}:nat8" for b in bytes.fromhex("’$LEDGER\_ACC’")]) + “}”)’)’ })’

I get the result:  
(record { 5\_035\_232 = 100\_000\_000\_000 : nat64 })

Which makes me think the canister is setup correctly.

All I do next is go over to my main.mo file, which you can see here:

> <https://github.com/jamesbeadle/football_god/blob/master/src/football_god_backend/main.mo>

and I get the error:  
uses Candid types without corresponding Motoko type

Does any of this help?

Thanks

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [April 4, 2023, 9:53am UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/19 "2023-04-04T09:53:17Z")

</div>

> [@jamesbeadle](#):
>
> Which makes me think the canister is setup correctly.

I agree, looks fine to me too.

I don’t have time to dig deep into your code right now. I’ll ask the Motoko team if they have any advice to debug this further.

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [April 4, 2023, 12:42pm UTC](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183/20 "2023-04-04T12:42:52Z")

</div>

I believe that the problem might be with the did file that motoko is importing (ledger.public.did). I can’t see it in the repo, but I guess it’s downloaded from here:

> <https://github.com/dfinity/ic/blob/master/rs/rosetta-api/ledger.did>

(If you can share your version of the ledger did, used by Motoko, that would be helpful.)

This line [ic/ledger.did at master · dfinity/ic · GitHub](https://github.com/dfinity/ic/blob/master/rs/rosetta-api/ledger.did#L99) of that did file includes  
the service argument, used by dfx when installing the canister. The installed canister, that motoko wants to talk to, shouldn’t have the argument and the did file used needs to look something like this (note the commented out argument to the service):

```auto
type Tokens = record {
     e8s : nat64;
};

type Duration = record {
    secs: nat64;
    nanos: nat32;
};

// Number of nanoseconds from the UNIX epoch in UTC timezone.
type TimeStamp = record {
    timestamp_nanos: nat64;
};

type ArchiveOptions = record {
    trigger_threshold : nat64;
    num_blocks_to_archive : nat64;
    node_max_memory_size_bytes: opt nat64;
    max_message_size_bytes: opt nat64;
    controller_id: principal;
    cycles_for_archive_creation: opt nat64;
};

// Height of a ledger block.
type BlockIndex = nat64;

// A number associated with a transaction.
// Can be set by the caller in `send` call as a correlation identifier.
type Memo = nat64;

// Account identifier encoded as a 64-byte ASCII hex string.
type AccountIdentifier = text;

// Subaccount is an arbitrary 32-byte byte array.
type SubAccount = blob;

type Transfer = variant {
    Burn: record {
        from: AccountIdentifier;
        amount: Tokens;
    };
    Mint: record {
        to: AccountIdentifier;
        amount: Tokens;
    };
    Send: record {
        from: AccountIdentifier;
        to: AccountIdentifier;
        amount: Tokens;
    };
};

type Transaction = record {
    transfer: Transfer;
    memo: Memo;
    created_at: BlockIndex;
};

// Arguments for the `send_dfx` call.
type SendArgs = record {
    memo: Memo;
    amount: Tokens;
    fee: Tokens;
    from_subaccount: opt SubAccount;
    to: AccountIdentifier;
    created_at_time: opt TimeStamp;
};

// Arguments for the `notify` call.
type NotifyCanisterArgs = record {
    // The of the block to send a notification about.
    block_height: BlockIndex;
    // Max fee, should be 10000 e8s.
    max_fee: Tokens;
    // Subaccount the payment came from.
    from_subaccount: opt SubAccount;
    // Canister that received the payment.
    to_canister: principal;
    // Subaccount that received the payment.
    to_subaccount: opt SubAccount;
};

type AccountBalanceArgs = record {
    account: AccountIdentifier;
};

type LedgerCanisterInitPayload = record {
    minting_account: AccountIdentifier;
    initial_values: vec record {AccountIdentifier; Tokens};
    max_message_size_bytes: opt nat64;
    transaction_window: opt Duration;
    archive_options: opt ArchiveOptions;
    send_whitelist: vec principal;
    transfer_fee: opt Tokens;
    token_symbol: opt text;
    token_name: opt text;
};

service: /* (LedgerCanisterInitPayload) -> */ { // <--- remove the argument type!
  send_dfx : (SendArgs) -> (BlockIndex);
  notify_dfx: (NotifyCanisterArgs) -> ();
  account_balance_dfx : (AccountBalanceArgs) -> (Tokens) query;
  notify_pb: () -> ();
}

```

[Next page](https://forum.dfinity.org/t/how-to-deploy-the-icp-ledger-locally/4183.md?page=2)
