diff --git a/.github/workflows/provision-darwin.sh b/.github/workflows/provision-darwin.sh index fb84438fc..6cc487b6e 100755 --- a/.github/workflows/provision-darwin.sh +++ b/.github/workflows/provision-darwin.sh @@ -18,7 +18,7 @@ rm node.pkg # Install DFINITY SDK. curl --location --output install-dfx.sh "https://internetcomputer.org/install.sh" -DFX_VERSION=${DFX_VERSION:=0.12.0} bash install-dfx.sh < <(yes Y) +DFX_VERSION=${DFX_VERSION:=0.14.3} bash install-dfx.sh < <(yes Y) rm install-dfx.sh dfx cache install diff --git a/.github/workflows/provision-linux.sh b/.github/workflows/provision-linux.sh index 308447a4e..35d8fd430 100755 --- a/.github/workflows/provision-linux.sh +++ b/.github/workflows/provision-linux.sh @@ -13,7 +13,7 @@ rm install-node.sh # Install DFINITY SDK. wget --output-document install-dfx.sh "https://internetcomputer.org/install.sh" -DFX_VERSION=${DFX_VERSION:=0.12.0} bash install-dfx.sh < <(yes Y) +DFX_VERSION=${DFX_VERSION:=0.14.3} bash install-dfx.sh < <(yes Y) rm install-dfx.sh dfx cache install diff --git a/motoko/ledger-transfer/demo.sh b/motoko/ledger-transfer/demo.sh index 3e770dfc9..8964f5e1d 100755 --- a/motoko/ledger-transfer/demo.sh +++ b/motoko/ledger-transfer/demo.sh @@ -3,20 +3,12 @@ dfx stop set -e trap 'dfx stop' EXIT -export IC_VERSION=2cb0afe1f49b8bbd4e60db234ca1f4a6f68ea115 -test -f ledger.wasm.gz || curl -o ledger.wasm.gz https://download.dfinity.systems/ic/${IC_VERSION}/canisters/ledger-canister_notify-method.wasm.gz -test -f ledger.wasm || gunzip ledger.wasm.gz -test -f ledger.private.did || curl -o ledger.private.did https://raw.githubusercontent.com/dfinity/ic/${IC_VERSION}/rs/rosetta-api/ledger.did -test -f ledger.public.did || curl -o ledger.public.did https://raw.githubusercontent.com/dfinity/ic/${IC_VERSION}/rs/rosetta-api/ledger_canister/ledger.did - dfx start --background --clean dfx identity new alice --disable-encryption || true -cat <<<"$(jq '.canisters.ledger.candid="ledger.private.did"' dfx.json)" >dfx.json export MINT_ACC=$(dfx --identity anonymous ledger account-id) export LEDGER_ACC=$(dfx ledger account-id) export ARCHIVE_CONTROLLER=$(dfx identity get-principal) -dfx deploy ledger --argument '(record {minting_account = "'${MINT_ACC}'"; initial_values = vec { record { "'${LEDGER_ACC}'"; record { e8s=100_000_000_000 } }; }; send_whitelist = vec {}})' -cat <<<"$(jq '.canisters.ledger.candid="ledger.public.did"' dfx.json)" >dfx.json +dfx deploy ledger --argument '(variant { Init = record {minting_account = "'${MINT_ACC}'"; initial_values = vec { record { "'${LEDGER_ACC}'"; record { e8s=100_000_000_000 } }; }; send_whitelist = vec {}}})' dfx canister call ledger account_balance '(record { account = '$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$LEDGER_ACC'")]) + "}")')' })' dfx deploy ledger_transfer diff --git a/motoko/ledger-transfer/dfx.json b/motoko/ledger-transfer/dfx.json index 3312714d0..4d4dc5fc9 100644 --- a/motoko/ledger-transfer/dfx.json +++ b/motoko/ledger-transfer/dfx.json @@ -9,8 +9,13 @@ }, "ledger": { "type": "custom", - "candid": "ledger.public.did", - "wasm": "ledger.wasm" + "candid": "https://raw.githubusercontent.com/dfinity/ic/a17247bd86c7aa4e87742bf74d108614580f216d/rs/rosetta-api/icp_ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic/a17247bd86c7aa4e87742bf74d108614580f216d/canisters/ledger-canister.wasm.gz", + "remote": { + "id": { + "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai" + } + } } }, "defaults": { @@ -20,4 +25,4 @@ } }, "version": 1 -} \ No newline at end of file +} diff --git a/motoko/ledger-transfer/ledger.public.did b/motoko/ledger-transfer/ledger.public.did deleted file mode 100644 index 155ea76b7..000000000 --- a/motoko/ledger-transfer/ledger.public.did +++ /dev/null @@ -1,249 +0,0 @@ -// This is the official Ledger interface that is guaranteed to be backward compatible. - -// Amount of tokens, measured in 10^-8 of a token. -type Tokens = record { - e8s : nat64; -}; - -// Number of nanoseconds from the UNIX epoch in UTC timezone. -type TimeStamp = record { - timestamp_nanos: nat64; -}; - -// AccountIdentifier is a 32-byte array. -// The first 4 bytes is big-endian encoding of a CRC32 checksum of the last 28 bytes. -type AccountIdentifier = blob; - -// Subaccount is an arbitrary 32-byte byte array. -// Ledger uses subaccounts to compute the source address, which enables one -// principal to control multiple ledger accounts. -type SubAccount = blob; - -// Sequence number of a block produced by the ledger. -type BlockIndex = nat64; - -// An arbitrary number associated with a transaction. -// The caller can set it in a `transfer` call as a correlation identifier. -type Memo = nat64; - -// Arguments for the `transfer` call. -type TransferArgs = record { - // Transaction memo. - // See comments for the `Memo` type. - memo: Memo; - // The amount that the caller wants to transfer to the destination address. - amount: Tokens; - // The amount that the caller pays for the transaction. - // Must be 10000 e8s. - fee: Tokens; - // The subaccount from which the caller wants to transfer funds. - // If null, the ledger uses the default (all zeros) subaccount to compute the source address. - // See comments for the `SubAccount` type. - from_subaccount: opt SubAccount; - // The destination account. - // If the transfer is successful, the balance of this address increases by `amount`. - to: AccountIdentifier; - // The point in time when the caller created this request. - // If null, the ledger uses current IC time as the timestamp. - created_at_time: opt TimeStamp; -}; - -type TransferError = variant { - // The fee that the caller specified in the transfer request was not the one that ledger expects. - // The caller can change the transfer fee to the `expected_fee` and retry the request. - BadFee : record { expected_fee : Tokens; }; - // The account specified by the caller doesn't have enough funds. - InsufficientFunds : record { balance: Tokens; }; - // The request is too old. - // The ledger only accepts requests created within 24 hours window. - // This is a non-recoverable error. - TxTooOld : record { allowed_window_nanos: nat64 }; - // The caller specified `created_at_time` that is too far in future. - // The caller can retry the request later. - TxCreatedInFuture : null; - // The ledger has already executed the request. - // `duplicate_of` field is equal to the index of the block containing the original transaction. - TxDuplicate : record { duplicate_of: BlockIndex; } -}; - -type TransferResult = variant { - Ok : BlockIndex; - Err : TransferError; -}; - -// Arguments for the `account_balance` call. -type AccountBalanceArgs = record { - account: AccountIdentifier; -}; - -type TransferFeeArg = record {}; - -type TransferFee = record { - // The fee to pay to perform a transfer - transfer_fee: Tokens; -}; - -type GetBlocksArgs = record { - // The index of the first block to fetch. - start : BlockIndex; - // Max number of blocks to fetch. - length : nat64; -}; - -type Operation = variant { - Mint : record { - to : AccountIdentifier; - amount : Tokens; - }; - Burn : record { - from : AccountIdentifier; - amount : Tokens; - }; - Transfer : record { - from : AccountIdentifier; - to : AccountIdentifier; - amount : Tokens; - fee : Tokens; - }; -}; - -type Transaction = record { - memo : Memo; - operation : opt Operation; - created_at_time : TimeStamp; -}; - -type Block = record { - parent_hash : opt blob; - transaction : Transaction; - timestamp : TimeStamp; -}; - -// A prefix of the block range specified in the [GetBlocksArgs] request. -type BlockRange = record { - // A prefix of the requested block range. - // The index of the first block is equal to [GetBlocksArgs.from]. - // - // Note that the number of blocks might be less than the requested - // [GetBlocksArgs.len] for various reasons, for example: - // - // 1. The query might have hit the replica with an outdated state - // that doesn't have the full block range yet. - // 2. The requested range is too large to fit into a single reply. - // - // NOTE: the list of blocks can be empty if: - // 1. [GetBlocksArgs.len] was zero. - // 2. [GetBlocksArgs.from] was larger than the last block known to the canister. - blocks : vec Block; -}; - -// An error indicating that the arguments passed to [QueryArchiveFn] were invalid. -type QueryArchiveError = variant { - // [GetBlocksArgs.from] argument was smaller than the first block - // served by the canister that received the request. - BadFirstBlockIndex : record { - requested_index : BlockIndex; - first_valid_index : BlockIndex; - }; - - // Reserved for future use. - Other : record { - error_code : nat64; - error_message : text; - }; -}; - -type QueryArchiveResult = variant { - // Successfully fetched zero or more blocks. - Ok : BlockRange; - // The [GetBlocksArgs] request was invalid. - Err : QueryArchiveError; -}; - -// A function that is used for fetching archived ledger blocks. -type QueryArchiveFn = func (GetBlocksArgs) -> (QueryArchiveResult) query; - -// The result of a "query_blocks" call. -// -// The structure of the result is somewhat complicated because the main ledger canister might -// not have all the blocks that the caller requested: One or more "archive" canisters might -// store some of the requested blocks. -// -// Note: as of Q4 2021 when this interface is authored, the IC doesn't support making nested -// query calls within a query call. -type QueryBlocksResponse = record { - // The total number of blocks in the chain. - // If the chain length is positive, the index of the last block is `chain_len - 1`. - chain_length : nat64; - - // System certificate for the hash of the latest block in the chain. - // Only present if `query_blocks` is called in a non-replicated query context. - certificate : opt blob; - - // List of blocks that were available in the ledger when it processed the call. - // - // The blocks form a contiguous range, with the first block having index - // [first_block_index] (see below), and the last block having index - // [first_block_index] + len(blocks) - 1. - // - // The block range can be an arbitrary sub-range of the originally requested range. - blocks : vec Block; - - // The index of the first block in "blocks". - // If the blocks vector is empty, the exact value of this field is not specified. - first_block_index : BlockIndex; - - // Encoding of instructions for fetching archived blocks whose indices fall into the - // requested range. - // - // For each entry `e` in [archived_blocks], `[e.from, e.from + len)` is a sub-range - // of the originally requested block range. - archived_blocks : vec record { - // The index of the first archived block that can be fetched using the callback. - start : BlockIndex; - - // The number of blocks that can be fetch using the callback. - length : nat64; - - // The function that should be called to fetch the archived blocks. - // The range of the blocks accessible using this function is given by [from] - // and [len] fields above. - callback : QueryArchiveFn; - }; -}; - -type Archive = record { - canister_id: principal; -}; - -type Archives = record { - archives: vec Archive; -}; - -service : { - // Transfers tokens from a subaccount of the caller to the destination address. - // The source address is computed from the principal of the caller and the specified subaccount. - // When successful, returns the index of the block containing the transaction. - transfer : (TransferArgs) -> (TransferResult); - - // Returns the amount of Tokens on the specified account. - account_balance : (AccountBalanceArgs) -> (Tokens) query; - - // Returns the current transfer_fee. - transfer_fee : (TransferFeeArg) -> (TransferFee) query; - - // Queries blocks in the specified range. - query_blocks : (GetBlocksArgs) -> (QueryBlocksResponse) query; - - // Returns token symbol. - symbol : () -> (record { symbol: text }) query; - - // Returns token name. - name : () -> (record { name: text }) query; - - // Returns token decimals. - decimals : () -> (record { decimals: nat32 }) query; - - // Returns the existing archive canisters information. - archives : () -> (Archives) query; -} diff --git a/motoko/ledger-transfer/src/ledger_transfer/main.mo b/motoko/ledger-transfer/src/ledger_transfer/main.mo index 2a4972564..8dbb0ed78 100644 --- a/motoko/ledger-transfer/src/ledger_transfer/main.mo +++ b/motoko/ledger-transfer/src/ledger_transfer/main.mo @@ -2,6 +2,7 @@ import Ledger "canister:ledger"; import Debug "mo:base/Debug"; import Error "mo:base/Error"; +import Blob "mo:base/Blob"; import Int "mo:base/Int"; import HashMap "mo:base/HashMap"; import List "mo:base/List"; @@ -60,7 +61,7 @@ actor Self { // Returns current balance on the default account of this canister. public func canisterBalance() : async Ledger.Tokens { - await Ledger.account_balance({ account = myAccountId() }) + await Ledger.account_balance({ account = Blob.toArray(myAccountId()) }) }; // Rewards the most prolific author of the last week with 1 token. @@ -92,7 +93,7 @@ actor Self { let res = await Ledger.transfer({ memo = Nat64.fromNat(maxPosts); from_subaccount = null; - to = Account.accountIdentifier(principal, Account.defaultSubaccount()); + to = Blob.toArray(Account.accountIdentifier(principal, Account.defaultSubaccount())); amount = { e8s = 100_000_000 }; fee = { e8s = 10_000 }; created_at_time = ?{ timestamp_nanos = Nat64.fromNat(Int.abs(now)) };