diff --git a/Makefile b/Makefile index 889f43c..23ff9d7 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ build: node_modules .PHONY: install .SILENT: install install: build - dfx canister install identity --mode reinstall --yes + dfx canister install identity --argument '(null)' --mode reinstall --yes $(shell make/install_ledger.sh) $(shell make/install_ledger_index.sh) dfx canister install github --mode reinstall --yes @@ -31,7 +31,7 @@ install: build .PHONY: upgrade .SILENT: upgrade upgrade: build - dfx canister install identity --mode=upgrade + dfx canister install identity --argument '(null)' --mode=upgrade dfx canister install icrc1_ledger --mode=upgrade dfx canister install icrc1_index --mode=upgrade dfx canister install github --mode=upgrade @@ -41,6 +41,8 @@ upgrade: build .SILENT: clean clean: rm -fr .dfx + rm -fr node_modules + rm -fr target # tests .PHONY: test-1 diff --git a/icp/icrc1/index/ic-icrc1-index.wasm.gz b/icp/icrc1/index/ic-icrc1-index.wasm.gz index 4a5ce2f..adb0349 100644 Binary files a/icp/icrc1/index/ic-icrc1-index.wasm.gz and b/icp/icrc1/index/ic-icrc1-index.wasm.gz differ diff --git a/icp/icrc1/index/index.did b/icp/icrc1/index/index.did index d5b495d..a6b35d0 100644 --- a/icp/icrc1/index/index.did +++ b/icp/icrc1/index/index.did @@ -5,40 +5,48 @@ type Account = record { owner : principal; subaccount : opt blob }; type SubAccount = blob; type Transaction = record { - kind : text; - mint : opt record { - amount : nat; - to : Account; - memo : opt blob; - created_at_time : opt nat64; - }; - burn : opt record { - amount : nat; - from : Account; - spender : opt Account; - memo : opt blob; - created_at_time : opt nat64; - }; - transfer : opt record { - amount : nat; - from : Account; - to : Account; - spender : opt Account; - memo : opt blob; - created_at_time : opt nat64; - fee : opt nat; - }; - approve : opt record { - amount : nat; - from : Account; - spender : opt Account; - expected_allowance : opt nat; - expires_at : opt nat64; - memo : opt blob; - created_at_time : opt nat64; - fee : opt nat; - }; - timestamp : nat64; + burn : opt Burn; + kind : text; + mint : opt Mint; + approve : opt Approve; + timestamp : nat64; + transfer : opt Transfer; +}; + +type Approve = record { + fee : opt nat; + from : Account; + memo : opt vec nat8; + created_at_time : opt nat64; + amount : nat; + expected_allowance : opt nat; + expires_at : opt nat64; + spender : Account; +}; + +type Burn = record { + from : Account; + memo : opt vec nat8; + created_at_time : opt nat64; + amount : nat; + spender : opt Account; +}; + +type Mint = record { + to : Account; + memo : opt vec nat8; + created_at_time : opt nat64; + amount : nat; +}; + +type Transfer = record { + to : Account; + fee : opt nat; + from : Account; + memo : opt vec nat8; + created_at_time : opt nat64; + amount : nat; + spender : opt Account; }; type GetAccountTransactionsArgs = record { @@ -85,4 +93,4 @@ service : (InitArgs) -> { get_account_transactions : (GetAccountTransactionsArgs) -> (GetTransactionsResult); ledger_id : () -> (principal) query; list_subaccounts : (ListSubaccountsArgs) -> (vec SubAccount) query; -} \ No newline at end of file +} diff --git a/icp/icrc1/ledger/ic-icrc1-ledger.wasm.gz b/icp/icrc1/ledger/ic-icrc1-ledger.wasm.gz index 0899c8d..ae4c78a 100644 Binary files a/icp/icrc1/ledger/ic-icrc1-ledger.wasm.gz and b/icp/icrc1/ledger/ic-icrc1-ledger.wasm.gz differ diff --git a/icp/icrc1/ledger/ledger.did b/icp/icrc1/ledger/ledger.did index c0e59ef..e2799db 100644 --- a/icp/icrc1/ledger/ledger.did +++ b/icp/icrc1/ledger/ledger.did @@ -6,6 +6,52 @@ type Timestamp = nat64; type Duration = nat64; type Tokens = nat; type TxIndex = nat; +type Allowance = record { allowance : nat; expires_at : opt Timestamp }; +type AllowanceArgs = record { account : Account; spender : Account }; +type Approve = record { + fee : opt nat; + from : Account; + memo : opt blob; + created_at_time : opt Timestamp; + amount : nat; + expected_allowance : opt nat; + expires_at : opt Timestamp; + spender : Account; +}; +type ApproveArgs = record { + fee : opt nat; + memo : opt blob; + from_subaccount : opt blob; + created_at_time : opt Timestamp; + amount : nat; + expected_allowance : opt nat; + expires_at : opt Timestamp; + spender : Account; +}; +type ApproveError = variant { + GenericError : record { message : text; error_code : nat }; + TemporarilyUnavailable; + Duplicate : record { duplicate_of : BlockIndex }; + BadFee : record { expected_fee : nat }; + AllowanceChanged : record { current_allowance : nat }; + CreatedInFuture : record { ledger_time : Timestamp }; + TooOld; + Expired : record { ledger_time : Timestamp }; + InsufficientFunds : record { balance : nat }; +}; +type ApproveResult = variant { Ok : BlockIndex; Err : ApproveError }; + +type HttpRequest = record { + url : text; + method : text; + body : blob; + headers : vec record { text; text }; +}; +type HttpResponse = record { + body : blob; + headers : vec record { text; text }; + status_code : nat16; +}; type Account = record { owner : principal; @@ -26,7 +72,7 @@ type TransferError = variant { BadBurn : record { min_burn_amount : Tokens }; InsufficientFunds : record { balance : Tokens }; TooOld; - CreatedInFuture : record { ledger_time : nat64 }; + CreatedInFuture : record { ledger_time : Timestamp }; TemporarilyUnavailable; Duplicate : record { duplicate_of : BlockIndex }; GenericError : record { error_code : nat; message : text }; @@ -60,29 +106,47 @@ type InitArgs = record { token_name : text; metadata : vec record { text; MetadataValue }; initial_balances : vec record { Account; nat }; + feature_flags : opt FeatureFlags; + maximum_number_of_accounts : opt nat64; + accounts_overflow_trim_quantity : opt nat64; archive_options : record { num_blocks_to_archive : nat64; + max_transactions_per_response : opt nat64; trigger_threshold : nat64; max_message_size_bytes : opt nat64; cycles_for_archive_creation : opt nat64; node_max_memory_size_bytes : opt nat64; controller_id : principal; + more_controller_ids : opt vec principal; }; - feature_flags : opt FeatureFlags; }; type ChangeFeeCollector = variant { Unset; SetTo: Account; }; +type ChangeArchiveOptions = record { + num_blocks_to_archive : opt nat64; + max_transactions_per_response : opt nat64; + trigger_threshold : opt nat64; + max_message_size_bytes : opt nat64; + cycles_for_archive_creation : opt nat64; + node_max_memory_size_bytes : opt nat64; + controller_id : opt principal; + more_controller_ids : opt vec principal; +}; + type UpgradeArgs = record { metadata : opt vec record { text; MetadataValue }; token_symbol : opt text; token_name : opt text; - transfer_fee : opt nat64; + transfer_fee : opt nat; change_fee_collector : opt ChangeFeeCollector; max_memo_length : opt nat16; feature_flags : opt FeatureFlags; + maximum_number_of_accounts: opt nat64; + accounts_overflow_trim_quantity: opt nat64; + change_archive_options : opt ChangeArchiveOptions; }; type LedgerArg = variant { @@ -158,38 +222,47 @@ type TransactionRange = record { type QueryArchiveFn = func (GetTransactionsRequest) -> (TransactionRange) query; type Transaction = record { - kind : text; - mint : opt record { - amount : nat; - to : Account; - memo : opt blob; - created_at_time : opt nat64; - }; - burn : opt record { - amount : nat; - from : Account; - memo : opt blob; - created_at_time : opt nat64; - }; - transfer : opt record { - amount : nat; - from : Account; - to : Account; - memo : opt blob; - created_at_time : opt nat64; - fee : opt nat; - }; - timestamp : nat64; -}; - -type Value = variant { - Blob : blob; - Text : text; + burn : opt Burn; + kind : text; + mint : opt Mint; + approve : opt Approve; + timestamp : Timestamp; + transfer : opt Transfer; +}; + +type Burn = record { + from : Account; + memo : opt blob; + created_at_time : opt Timestamp; + amount : nat; + spender : opt Account; +}; + +type Mint = record { + to : Account; + memo : opt blob; + created_at_time : opt Timestamp; + amount : nat; +}; + +type Transfer = record { + to : Account; + fee : opt nat; + from : Account; + memo : opt blob; + created_at_time : opt Timestamp; + amount : nat; + spender : opt Account; +}; + +type Value = variant { + Blob : blob; + Text : text; Nat : nat; - Nat64: nat64; + Nat64: nat64; Int : int; - Array : vec Value; - Map : Map; + Array : vec Value; + Map : Map; }; type Map = vec record { text; Value }; @@ -268,43 +341,7 @@ type DataCertificate = record { hash_tree : blob; }; -type ApproveArgs = record { - from_subaccount : opt Subaccount; - spender : Account; - amount : Tokens; - expected_allowance : opt Tokens; - expires_at : opt Timestamp; - fee : opt Tokens; - memo : opt blob; - created_at_time: opt Timestamp; -}; - -type ApproveError = variant { - BadFee : record { expected_fee : Tokens }; - InsufficientFunds : record { balance : Tokens }; - AllowanceChanged : record { current_allowance : Tokens }; - Expired : record { ledger_time : nat64 }; - TooOld; - CreatedInFuture : record { ledger_time : nat64 }; - Duplicate : record { duplicate_of : BlockIndex }; - TemporarilyUnavailable; - GenericError : record { error_code : nat; message : text }; -}; - -type ApproveResult = variant { - Ok : BlockIndex; - Err : ApproveError; -}; - -type AllowanceArgs = record { - account : Account; - spender : Account; -}; - -type Allowance = record { - allowance : Tokens; - expires_at : opt Timestamp; -}; +type StandardRecord = record { url : text; name : text }; type TransferFromArgs = record { spender_subaccount : opt Subaccount; @@ -327,13 +364,73 @@ type TransferFromError = variant { InsufficientFunds : record { balance : Tokens }; InsufficientAllowance : record { allowance : Tokens }; TooOld; - CreatedInFuture : record { ledger_time : nat64 }; + CreatedInFuture : record { ledger_time : Timestamp }; Duplicate : record { duplicate_of : BlockIndex }; TemporarilyUnavailable; GenericError : record { error_code : nat; message : text }; }; +type ArchiveInfo = record { + canister_id: principal; + block_range_start: BlockIndex; + block_range_end: BlockIndex; +}; + +type ICRC3Value = variant { + Blob : blob; + Text : text; + Nat : nat; + Int : int; + Array : vec ICRC3Value; + Map : vec record { text; ICRC3Value }; +}; + +type GetArchivesArgs = record { + // The last archive seen by the client. + // The Ledger will return archives coming + // after this one if set, otherwise it + // will return the first archives. + from : opt principal; +}; + +type GetArchivesResult = vec record { + // The id of the archive + canister_id : principal; + + // The first block in the archive + start : nat; + + // The last block in the archive + end : nat; +}; + +type GetBlocksResult = record { + // Total number of blocks in the + // block log + log_length : nat; + + blocks : vec record { id : nat; block: ICRC3Value }; + + archived_blocks : vec record { + args : vec GetBlocksArgs; + callback : func (vec GetBlocksArgs) -> (GetBlocksResult) query; + }; +}; + +type ICRC3DataCertificate = record { + // See https://internetcomputer.org/docs/current/references/ic-interface-spec#certification + certificate : blob; + + // CBOR encoded hash_tree + hash_tree : blob; +}; + service : (ledger_arg : LedgerArg) -> { + archives : () -> (vec ArchiveInfo) query; + get_transactions : (GetTransactionsRequest) -> (GetTransactionsResponse) query; + get_blocks : (GetBlocksArgs) -> (GetBlocksResponse) query; + get_data_certificate : () -> (DataCertificate) query; + icrc1_name : () -> (text) query; icrc1_symbol : () -> (text) query; icrc1_decimals : () -> (nat8) query; @@ -343,11 +440,14 @@ service : (ledger_arg : LedgerArg) -> { icrc1_minting_account : () -> (opt Account) query; icrc1_balance_of : (Account) -> (Tokens) query; icrc1_transfer : (TransferArg) -> (TransferResult); - icrc1_supported_standards : () -> (vec record { name : text; url : text }) query; - get_transactions : (GetTransactionsRequest) -> (GetTransactionsResponse) query; - get_blocks : (GetBlocksArgs) -> (GetBlocksResponse) query; - get_data_certificate : () -> (DataCertificate) query; + icrc1_supported_standards : () -> (vec StandardRecord) query; + icrc2_approve : (ApproveArgs) -> (ApproveResult); icrc2_allowance : (AllowanceArgs) -> (Allowance) query; icrc2_transfer_from : (TransferFromArgs) -> (TransferFromResult); -} \ No newline at end of file + + icrc3_get_archives : (GetArchivesArgs) -> (GetArchivesResult) query; + icrc3_get_tip_certificate : () -> (opt ICRC3DataCertificate) query; + icrc3_get_blocks : (vec GetBlocksArgs) -> (GetBlocksResult) query; + icrc3_supported_block_types : () -> (vec record { block_type : text; url : text }) query; +} diff --git a/make/install_ledger.sh b/make/install_ledger.sh index 6828a2f..64ecf8e 100755 --- a/make/install_ledger.sh +++ b/make/install_ledger.sh @@ -2,8 +2,8 @@ set -e -TOKEN_NAME=PROTK -TOKEN_SYMBOL=PRO +TOKEN_NAME="Local ckBTC" +TOKEN_SYMBOL=LckBTC PRE_MINTED_TOKENS=10_000_000_000 TRANSFER_FEE=10_000 TRIGGER_THRESHOLD=2000 @@ -11,36 +11,25 @@ NUM_OF_BLOCK_TO_ARCHIVE=1000 CYCLE_FOR_ARCHIVE_CREATION=10000000000000 FEATURE_FLAGS=true -# FIXME: this should be used as minting_account owner -MINTER_ACCOUNT_ID=$(dfx ledger account-id) -DEPLOY_ID=$(dfx identity get-principal) +MINTER=$(dfx identity get-principal) +dfx identity use default +DEFAULT=$(dfx identity get-principal) ARCHIVE_CONTROLLER=$(dfx identity get-principal) -dfx canister install icrc1_ledger --mode reinstall --yes --argument \ - " \ - (variant { \ - Init = record { \ - decimals = null; \ - token_symbol = \"${TOKEN_SYMBOL}\"; \ - transfer_fee = ${TRANSFER_FEE}; \ - metadata = vec {}; \ - minting_account = record { \ - owner = principal \"${DEPLOY_ID}\"; \ - subaccount = null; \ - }; \ - initial_balances = vec { record { record { owner = principal \"${DEPLOY_ID}\"; }; ${PRE_MINTED_TOKENS}; }; }; \ - fee_collector_account = null; \ - archive_options = record { \ - num_blocks_to_archive = ${NUM_OF_BLOCK_TO_ARCHIVE}; \ - trigger_threshold = ${TRIGGER_THRESHOLD}; \ - max_message_size_bytes = null; \ - cycles_for_archive_creation = opt ${CYCLE_FOR_ARCHIVE_CREATION}; \ - node_max_memory_size_bytes = null; \ - controller_id = principal \"${ARCHIVE_CONTROLLER}\"; \ - }; \ - max_memo_length = null; \ - token_name = \"${TOKEN_NAME}\"; \ - feature_flags = opt record{icrc2 = ${FEATURE_FLAGS}}; \ - } \ - }) \ - " +dfx canister install icrc1_ledger --mode reinstall --yes --argument "(variant { Init = +record { + token_symbol = \"${TOKEN_SYMBOL}\"; + token_name = \"${TOKEN_NAME}\"; + minting_account = record { owner = principal \"${MINTER}\" }; + transfer_fee = ${TRANSFER_FEE}; + metadata = vec {}; + feature_flags = opt record{icrc2 = ${FEATURE_FLAGS}}; + initial_balances = vec { record { record { owner = principal \"${DEFAULT}\"; }; ${PRE_MINTED_TOKENS}; }; }; + archive_options = record { + num_blocks_to_archive = ${NUM_OF_BLOCK_TO_ARCHIVE}; + trigger_threshold = ${TRIGGER_THRESHOLD}; + controller_id = principal \"${ARCHIVE_CONTROLLER}\"; + cycles_for_archive_creation = opt ${CYCLE_FOR_ARCHIVE_CREATION}; + }; + } +})"