diff --git a/apps/wallet/package.json b/apps/wallet/package.json index b88a4cf92..fae4f0f7d 100644 --- a/apps/wallet/package.json +++ b/apps/wallet/package.json @@ -24,12 +24,13 @@ "format": "concurrently -n prettier,eslint -c auto \"prettier --ignore-path ../../.prettierignore --write .\" \"eslint --ext .js,.vue,.ts,.cjs --fix .\"" }, "dependencies": { - "@dfinity/agent": "2.1.2", - "@dfinity/auth-client": "2.1.2", - "@dfinity/candid": "2.1.2", - "@dfinity/identity": "2.1.2", - "@dfinity/principal": "2.1.2", - "@dfinity/ledger-icrc": "2.6.1", + "@dfinity/agent": "1.4.0", + "@dfinity/auth-client": "1.4.0", + "@dfinity/candid": "1.4.0", + "@dfinity/identity": "1.4.0", + "@dfinity/principal": "1.4.0", + "@dfinity/ledger-icrc": "2.3.3", + "@dfinity/utils": "2.3.1", "@dfinity/didc": "0.0.2", "@mdi/font": "7.4.47", "@mdi/js": "7.4.47", diff --git a/apps/wallet/src/components/assets/AssetDialog.vue b/apps/wallet/src/components/assets/AssetDialog.vue index 308f4f7ea..86e2757c8 100644 --- a/apps/wallet/src/components/assets/AssetDialog.vue +++ b/apps/wallet/src/components/assets/AssetDialog.vue @@ -149,7 +149,6 @@ const save = async (): Promise => { }, ], blockchain: [assertAndReturn(asset.value.blockchain, 'blockchain')], - decimals: [assertAndReturn(asset.value.decimals, 'decimals')], name: [assertAndReturn(asset.value.name, 'name')], symbol: [assertAndReturn(asset.value.symbol, 'symbol')], standards: [assertAndReturn(asset.value.standards, 'standards')], diff --git a/apps/wallet/src/components/assets/AssetForm.vue b/apps/wallet/src/components/assets/AssetForm.vue index 613202ba2..bf7ff51b7 100644 --- a/apps/wallet/src/components/assets/AssetForm.vue +++ b/apps/wallet/src/components/assets/AssetForm.vue @@ -69,7 +69,7 @@ :label="$t('pages.assets.forms.decimals')" variant="filled" density="comfortable" - :disabled="isViewMode" + :disabled="isViewMode || !!model.id" :prepend-icon="mdiDecimal" :rules="[requiredRule]" /> diff --git a/apps/wallet/src/components/requests/operations/EditAssetOperation.vue b/apps/wallet/src/components/requests/operations/EditAssetOperation.vue index 6060c5ae8..85b0b78c7 100644 --- a/apps/wallet/src/components/requests/operations/EditAssetOperation.vue +++ b/apps/wallet/src/components/requests/operations/EditAssetOperation.vue @@ -95,10 +95,6 @@ const fetchDetails = async () => { entry.symbol = props.operation.input.symbol[0]; } - if (props.operation.input.decimals !== undefined) { - entry.decimals = props.operation.input.decimals[0]; - } - if (props.operation.input.standards && props.operation.input.standards.length > 0) { entry.standards = props.operation.input.standards[0]; } diff --git a/apps/wallet/src/generated/station/station.did b/apps/wallet/src/generated/station/station.did index b0e197169..f6c7b3095 100644 --- a/apps/wallet/src/generated/station/station.did +++ b/apps/wallet/src/generated/station/station.did @@ -1711,6 +1711,8 @@ type ListAddressBookEntriesInput = record { blockchain : opt text; // The labels to search for, if provided only address book entries with the given labels will be returned. labels : opt vec text; + // The address formats to search for. + address_formats : opt vec text; // The pagination parameters. paginate : opt PaginationInput; }; @@ -1754,9 +1756,7 @@ type Asset = record { symbol : AssetSymbol; // The asset name (e.g. `Internet Computer`, `Bitcoin`, `Ethereum`, etc.) name : text; - // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`), - // also, in the case of non-native assets, it can contain other required - // information (e.g. `{"address": "0x1234"}`). + // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`). metadata : vec AssetMetadata; // The number of decimals used by the asset (e.g. `8` for `BTC`, `18` for `ETH`, etc.). decimals : nat32; @@ -2239,9 +2239,7 @@ type AddAssetOperationInput = record { symbol : AssetSymbol; // The asset name (e.g. `Internet Computer`, `Bitcoin`, `Ethereum`, etc.) name : text; - // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`), - // also, in the case of non-native assets, it can contain other required - // information (e.g. `{"address": "0x1234"}`). + // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`). metadata : vec AssetMetadata; // The number of decimals used by the asset (e.g. `8` for `BTC`, `18` for `ETH`, etc.). decimals : nat32; @@ -2265,8 +2263,6 @@ type EditAssetOperationInput = record { standards : opt vec text; // The asset symbol, e.g. "ICP" or "BTC". symbol : opt AssetSymbol; - // The number of decimals used by the asset (e.g. `8` for `BTC`, `18` for `ETH`, etc.). - decimals : opt nat32; // The metadata to change. change_metadata : opt ChangeMetadata; }; diff --git a/apps/wallet/src/generated/station/station.did.d.ts b/apps/wallet/src/generated/station/station.did.d.ts index 5a3675268..978bf06bb 100644 --- a/apps/wallet/src/generated/station/station.did.d.ts +++ b/apps/wallet/src/generated/station/station.did.d.ts @@ -340,7 +340,6 @@ export interface EditAddressBookEntryOperationInput { } export interface EditAssetOperation { 'input' : EditAssetOperationInput } export interface EditAssetOperationInput { - 'decimals' : [] | [number], 'standards' : [] | [Array], 'name' : [] | [string], 'blockchain' : [] | [string], @@ -703,6 +702,7 @@ export type ListAccountsResult = { { 'Err' : Error }; export interface ListAddressBookEntriesInput { 'ids' : [] | [Array], + 'address_formats' : [] | [Array], 'labels' : [] | [Array], 'blockchain' : [] | [string], 'addresses' : [] | [Array], diff --git a/apps/wallet/src/generated/station/station.did.js b/apps/wallet/src/generated/station/station.did.js index bf0bae377..9771ba395 100644 --- a/apps/wallet/src/generated/station/station.did.js +++ b/apps/wallet/src/generated/station/station.did.js @@ -381,7 +381,6 @@ export const idlFactory = ({ IDL }) => { 'ReplaceAllBy' : IDL.Vec(AssetMetadata), }); const EditAssetOperationInput = IDL.Record({ - 'decimals' : IDL.Opt(IDL.Nat32), 'standards' : IDL.Opt(IDL.Vec(IDL.Text)), 'name' : IDL.Opt(IDL.Text), 'blockchain' : IDL.Opt(IDL.Text), @@ -1181,6 +1180,7 @@ export const idlFactory = ({ IDL }) => { }); const ListAddressBookEntriesInput = IDL.Record({ 'ids' : IDL.Opt(IDL.Vec(UUID)), + 'address_formats' : IDL.Opt(IDL.Vec(IDL.Text)), 'labels' : IDL.Opt(IDL.Vec(IDL.Text)), 'blockchain' : IDL.Opt(IDL.Text), 'addresses' : IDL.Opt(IDL.Vec(IDL.Text)), diff --git a/apps/wallet/src/pages/AccountAssetPage.vue b/apps/wallet/src/pages/AccountAssetPage.vue index a0364effb..507352be0 100644 --- a/apps/wallet/src/pages/AccountAssetPage.vue +++ b/apps/wallet/src/pages/AccountAssetPage.vue @@ -407,7 +407,6 @@ const loadTransfers = async (): Promise< ) { return []; } - // const firstAddress = addresses.value[0]; const transfers = await chainApi.value.fetchTransfers({ fromDt: convertDate(filters.value.created.from, { time: 'start-of-day', diff --git a/apps/wallet/src/services/station.service.ts b/apps/wallet/src/services/station.service.ts index 3b44fb05c..731505cca 100644 --- a/apps/wallet/src/services/station.service.ts +++ b/apps/wallet/src/services/station.service.ts @@ -551,7 +551,15 @@ export class StationService { } async listAddressBook( - { limit, offset, blockchain, labels, ids, addresses }: ListAddressBookEntriesArgs = {}, + { + limit, + offset, + blockchain, + labels, + ids, + addresses, + address_formats, + }: ListAddressBookEntriesArgs = {}, verifiedCall = false, ): Promise> { const actor = verifiedCall ? this.verified_actor : this.actor; @@ -566,6 +574,7 @@ export class StationService { labels: labels ? [labels] : [], addresses: addresses ? [addresses] : [], ids: ids ? [ids] : [], + address_formats: address_formats ? [address_formats] : [], }); if (variantIs(result, 'Err')) { diff --git a/apps/wallet/src/types/station.types.ts b/apps/wallet/src/types/station.types.ts index e7423aeae..95b45ab98 100644 --- a/apps/wallet/src/types/station.types.ts +++ b/apps/wallet/src/types/station.types.ts @@ -146,6 +146,7 @@ export interface ListAddressBookEntriesArgs { blockchain?: string; labels?: []; ids?: UUID[]; + address_formats?: string[]; } export interface ListAssetsArgs { diff --git a/core/station/api/spec.did b/core/station/api/spec.did index b0e197169..f6c7b3095 100644 --- a/core/station/api/spec.did +++ b/core/station/api/spec.did @@ -1711,6 +1711,8 @@ type ListAddressBookEntriesInput = record { blockchain : opt text; // The labels to search for, if provided only address book entries with the given labels will be returned. labels : opt vec text; + // The address formats to search for. + address_formats : opt vec text; // The pagination parameters. paginate : opt PaginationInput; }; @@ -1754,9 +1756,7 @@ type Asset = record { symbol : AssetSymbol; // The asset name (e.g. `Internet Computer`, `Bitcoin`, `Ethereum`, etc.) name : text; - // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`), - // also, in the case of non-native assets, it can contain other required - // information (e.g. `{"address": "0x1234"}`). + // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`). metadata : vec AssetMetadata; // The number of decimals used by the asset (e.g. `8` for `BTC`, `18` for `ETH`, etc.). decimals : nat32; @@ -2239,9 +2239,7 @@ type AddAssetOperationInput = record { symbol : AssetSymbol; // The asset name (e.g. `Internet Computer`, `Bitcoin`, `Ethereum`, etc.) name : text; - // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`), - // also, in the case of non-native assets, it can contain other required - // information (e.g. `{"address": "0x1234"}`). + // The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`). metadata : vec AssetMetadata; // The number of decimals used by the asset (e.g. `8` for `BTC`, `18` for `ETH`, etc.). decimals : nat32; @@ -2265,8 +2263,6 @@ type EditAssetOperationInput = record { standards : opt vec text; // The asset symbol, e.g. "ICP" or "BTC". symbol : opt AssetSymbol; - // The number of decimals used by the asset (e.g. `8` for `BTC`, `18` for `ETH`, etc.). - decimals : opt nat32; // The metadata to change. change_metadata : opt ChangeMetadata; }; diff --git a/core/station/api/src/address_book.rs b/core/station/api/src/address_book.rs index 2504ada44..caa4dcbfe 100644 --- a/core/station/api/src/address_book.rs +++ b/core/station/api/src/address_book.rs @@ -77,6 +77,7 @@ pub struct ListAddressBookEntriesInputDTO { pub blockchain: Option, pub labels: Option>, pub paginate: Option, + pub address_formats: Option>, } #[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] diff --git a/core/station/api/src/asset.rs b/core/station/api/src/asset.rs index 242fc822d..b5b649ea0 100644 --- a/core/station/api/src/asset.rs +++ b/core/station/api/src/asset.rs @@ -18,9 +18,7 @@ pub struct AssetDTO { pub standards: Vec, /// The asset name (e.g. `Internet Computer`, `Bitcoin`, `Ethereum`, etc.) pub name: String, - /// The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`), - /// also, in the case of non-native assets, it can contain other required - /// information (e.g. `{"address": "0x1234"}`). + /// The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`). pub metadata: Vec, } @@ -51,7 +49,6 @@ pub struct EditAssetOperationInput { pub blockchain: Option, pub standards: Option>, pub symbol: Option, - pub decimals: Option, pub change_metadata: Option, } diff --git a/core/station/impl/src/core/init.rs b/core/station/impl/src/core/init.rs index 60ba49b96..936e5d5c4 100644 --- a/core/station/impl/src/core/init.rs +++ b/core/station/impl/src/core/init.rs @@ -171,11 +171,11 @@ lazy_static! { Resource::Asset(ResourceAction::Create), ), ( - Allow::user_groups(vec![*ADMIN_GROUP_ID]), + Allow::authenticated(), Resource::Asset(ResourceAction::List), ), ( - Allow::user_groups(vec![*ADMIN_GROUP_ID]), + Allow::authenticated(), Resource::Asset(ResourceAction::Read(ResourceId::Any)), ), ( diff --git a/core/station/impl/src/core/validation.rs b/core/station/impl/src/core/validation.rs index 2b74c7ff9..b7ebf79a8 100644 --- a/core/station/impl/src/core/validation.rs +++ b/core/station/impl/src/core/validation.rs @@ -199,7 +199,7 @@ impl EnsureExternalCanister { pub fn is_external_canister( principal: Principal, ) -> Result<(), ExternalCanisterValidationError> { - // todo: look into Asset repository and exclude the ledger_canister_id's + // todo: add a mutable denylist for external canisters if principal == Principal::management_canister() || principal == ic_cdk::api::id() || principal == MAINNET_LEDGER_CANISTER_ID diff --git a/core/station/impl/src/errors/asset.rs b/core/station/impl/src/errors/asset.rs index 50ba75aad..e71a78d11 100644 --- a/core/station/impl/src/errors/asset.rs +++ b/core/station/impl/src/errors/asset.rs @@ -23,9 +23,9 @@ pub enum AssetError { /// The given blockchain is unknown to the system. #[error(r#"The given blockchain is unknown to the system."#)] UnknownBlockchain { blockchain: String }, - /// The given blockchain standard is unknown to the system. - #[error(r#"The given blockchain standard is unknown to the system."#)] - UnknownBlockchainStandard { blockchain_standard: String }, + /// The given token standard is unknown to the system. + #[error(r#"The given token standard is unknown to the system."#)] + UnknownTokenStandard { token_standard: String }, /// The asset has failed validation. #[error(r#"The account has failed validation."#)] ValidationError { info: String }, @@ -50,13 +50,8 @@ impl DetailableError for AssetError { details.insert("blockchain".to_string(), blockchain.to_string()); Some(details) } - AssetError::UnknownBlockchainStandard { - blockchain_standard, - } => { - details.insert( - "blockchain_standard".to_string(), - blockchain_standard.to_string(), - ); + AssetError::UnknownTokenStandard { token_standard } => { + details.insert("token_standard".to_string(), token_standard.to_string()); Some(details) } AssetError::ValidationError { info } => { diff --git a/core/station/impl/src/mappers/address_book.rs b/core/station/impl/src/mappers/address_book.rs index 16d4324f6..853bb6b91 100644 --- a/core/station/impl/src/mappers/address_book.rs +++ b/core/station/impl/src/mappers/address_book.rs @@ -1,10 +1,12 @@ +use std::str::FromStr; + use super::HelperMapper; use crate::core::ic_cdk::next_time; use crate::errors::MapperError; use crate::mappers::blockchain::BlockchainMapper; use crate::models::{ AddAddressBookEntryOperationInput, AddressBookEntry, AddressBookEntryCallerPrivileges, - ListAddressBookEntriesInput, + AddressFormat, ListAddressBookEntriesInput, }; use orbit_essentials::types::UUID; use orbit_essentials::utils::timestamp_to_rfc3339; @@ -67,6 +69,14 @@ impl From for ListAddressBookEntriesInput { }), labels: input.labels, addresses: input.addresses, + address_formats: input.address_formats.map(|address_formats| { + address_formats + .into_iter() + .map(|address_format| { + AddressFormat::from_str(&address_format).expect("Invalid address format") + }) + .collect() + }), ids: input.ids.map(|ids| { ids.into_iter() .map(|id| { diff --git a/core/station/impl/src/mappers/request_operation.rs b/core/station/impl/src/mappers/request_operation.rs index 1862ccd2a..20442bdeb 100644 --- a/core/station/impl/src/mappers/request_operation.rs +++ b/core/station/impl/src/mappers/request_operation.rs @@ -1598,7 +1598,6 @@ impl From for station_api::EditAssetOperationInput { asset_id: Uuid::from_bytes(input.asset_id).hyphenated().to_string(), name: input.name, symbol: input.symbol, - decimals: input.decimals, change_metadata: input .change_metadata .map(|change_metadata| change_metadata.into()), @@ -1618,7 +1617,6 @@ impl From for EditAssetOperationInput { .as_bytes(), name: input.name, symbol: input.symbol, - decimals: input.decimals, change_metadata: input .change_metadata .map(|change_metadata| change_metadata.into()), diff --git a/core/station/impl/src/models/address_book.rs b/core/station/impl/src/models/address_book.rs index 2f9c4a06e..ca658bb9a 100644 --- a/core/station/impl/src/models/address_book.rs +++ b/core/station/impl/src/models/address_book.rs @@ -137,12 +137,13 @@ impl AddressBookEntry { } } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone)] pub struct ListAddressBookEntriesInput { pub ids: Option>, pub addresses: Option>, pub blockchain: Option, pub labels: Option>, + pub address_formats: Option>, } #[derive(CandidType, Deserialize, Debug, Clone)] diff --git a/core/station/impl/src/models/asset.rs b/core/station/impl/src/models/asset.rs index bfa69d3f3..c4bec6016 100644 --- a/core/station/impl/src/models/asset.rs +++ b/core/station/impl/src/models/asset.rs @@ -28,9 +28,7 @@ pub struct Asset { pub name: String, /// The number of decimal places that the asset supports (e.g. `8` for `BTC`, `18` for `ETH`, etc.) pub decimals: u32, - /// The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`), - /// also, in the case of non-native assets, it can contain other required - /// information (e.g. `{"address": "0x1234"}`). + /// The asset metadata (e.g. `{"logo": "https://example.com/logo.png"}`). pub metadata: Metadata, } diff --git a/core/station/impl/src/models/indexes/unique_index.rs b/core/station/impl/src/models/indexes/unique_index.rs index eaa1f443c..3056208f6 100644 --- a/core/station/impl/src/models/indexes/unique_index.rs +++ b/core/station/impl/src/models/indexes/unique_index.rs @@ -19,8 +19,8 @@ pub enum UniqueIndexKey { UserIdentity(Principal), UserName(String), AssetSymbolBlockchain( - String, // Symbol String, // Blockchain + String, // Symbol ), } diff --git a/core/station/impl/src/models/request_operation.rs b/core/station/impl/src/models/request_operation.rs index b1f8ba3cc..65c2904e1 100644 --- a/core/station/impl/src/models/request_operation.rs +++ b/core/station/impl/src/models/request_operation.rs @@ -114,7 +114,6 @@ pub struct EditAssetOperationInput { pub asset_id: AssetId, pub name: Option, pub symbol: Option, - pub decimals: Option, pub change_metadata: Option, pub blockchain: Option, pub standards: Option>, diff --git a/core/station/impl/src/models/resource.rs b/core/station/impl/src/models/resource.rs index f58b11f63..a93fa52d9 100644 --- a/core/station/impl/src/models/resource.rs +++ b/core/station/impl/src/models/resource.rs @@ -627,25 +627,9 @@ impl Resource { Resource::Asset(action) => match action { ResourceAction::Create => vec![Resource::Asset(ResourceAction::Create)], - ResourceAction::Delete(ResourceId::Id(id)) => { - vec![ - Resource::Asset(ResourceAction::Delete(ResourceId::Id(*id))), - Resource::Asset(ResourceAction::Delete(ResourceId::Any)), - ] - } ResourceAction::List => vec![Resource::Asset(ResourceAction::List)], - ResourceAction::Read(ResourceId::Id(id)) => { - vec![ - Resource::Asset(ResourceAction::Read(ResourceId::Id(*id))), - Resource::Asset(ResourceAction::Read(ResourceId::Any)), - ] - } - ResourceAction::Update(ResourceId::Id(id)) => { - vec![ - Resource::Asset(ResourceAction::Update(ResourceId::Id(*id))), - Resource::Asset(ResourceAction::Update(ResourceId::Any)), - ] - } + + // Any resource id ResourceAction::Update(ResourceId::Any) => { vec![Resource::Asset(ResourceAction::Update(ResourceId::Any))] } @@ -655,6 +639,35 @@ impl Resource { ResourceAction::Delete(ResourceId::Any) => { vec![Resource::Asset(ResourceAction::Delete(ResourceId::Any))] } + + // Specific resource id + ResourceAction::Delete(ResourceId::Id(id)) => { + let mut associated_resources = + Resource::Asset(ResourceAction::Delete(ResourceId::Any)).to_expanded_list(); + + associated_resources + .push(Resource::Asset(ResourceAction::Delete(ResourceId::Id(*id)))); + + associated_resources + } + ResourceAction::Read(ResourceId::Id(id)) => { + let mut associated_resources = + Resource::Asset(ResourceAction::Read(ResourceId::Any)).to_expanded_list(); + + associated_resources + .push(Resource::Asset(ResourceAction::Read(ResourceId::Id(*id)))); + + associated_resources + } + ResourceAction::Update(ResourceId::Id(id)) => { + let mut associated_resources = + Resource::Asset(ResourceAction::Update(ResourceId::Any)).to_expanded_list(); + + associated_resources + .push(Resource::Asset(ResourceAction::Update(ResourceId::Id(*id)))); + + associated_resources + } }, } } diff --git a/core/station/impl/src/repositories/address_book.rs b/core/station/impl/src/repositories/address_book.rs index 69499bb1b..ee0a057f6 100644 --- a/core/station/impl/src/repositories/address_book.rs +++ b/core/station/impl/src/repositories/address_book.rs @@ -6,7 +6,7 @@ use crate::{ }, models::{ indexes::unique_index::UniqueIndexKey, AddressBookEntry, AddressBookEntryId, - AddressBookEntryKey, Blockchain, + AddressBookEntryKey, AddressFormat, Blockchain, }, }; use ic_stable_structures::{memory_manager::VirtualMemory, StableBTreeMap}; @@ -207,6 +207,10 @@ impl AddressBookRepository { entries.retain(|entry| addresses.contains(&entry.address)); } + if let Some(address_formats) = where_clause.address_formats { + entries.retain(|entry| address_formats.contains(&entry.address_format)); + } + entries.sort(); entries @@ -219,6 +223,7 @@ pub struct AddressBookWhereClause { pub labels: Option>, pub addresses: Option>, pub ids: Option>, + pub address_formats: Option>, } #[cfg(test)] @@ -280,4 +285,39 @@ mod tests { assert!(result.contains(&address_book_entry_0)); assert!(result.contains(&address_book_entry_1)); } + + #[test] + fn test_find_by_address_formats() { + let repository = AddressBookRepository::default(); + let mut address_book_entry_0 = address_book_entry_test_utils::mock_address_book_entry(); + let mut address_book_entry_1 = address_book_entry_test_utils::mock_address_book_entry(); + address_book_entry_0.id = [1; 16]; + address_book_entry_1.id = [2; 16]; + + address_book_entry_0.address_format = AddressFormat::ICPAccountIdentifier; + address_book_entry_1.address_format = AddressFormat::ICRC1Account; + + repository.insert(address_book_entry_0.to_key(), address_book_entry_0.clone()); + repository.insert(address_book_entry_1.to_key(), address_book_entry_1.clone()); + + let result = repository.find_where(AddressBookWhereClause { + blockchain: None, + labels: None, + addresses: None, + ids: None, + address_formats: Some(vec![AddressFormat::ICPAccountIdentifier]), + }); + assert!(result.contains(&address_book_entry_0)); + assert_eq!(result.len(), 1); + + let result = repository.find_where(AddressBookWhereClause { + blockchain: None, + labels: None, + addresses: None, + ids: None, + address_formats: Some(vec![AddressFormat::ICRC1Account]), + }); + assert!(result.contains(&address_book_entry_1)); + assert_eq!(result.len(), 1); + } } diff --git a/core/station/impl/src/services/account.rs b/core/station/impl/src/services/account.rs index 8c6aebdaa..491885b42 100644 --- a/core/station/impl/src/services/account.rs +++ b/core/station/impl/src/services/account.rs @@ -156,9 +156,9 @@ impl AccountService { let mut new_account = AccountMapper::from_create_input(input.to_owned(), *uuid.as_bytes(), None)?; - let dedulicated_asset_ids = input.assets.iter().cloned().collect::>(); + let deduplicated_asset_ids = input.assets.iter().cloned().collect::>(); - for asset_id in dedulicated_asset_ids.iter() { + for asset_id in deduplicated_asset_ids.iter() { let asset = self.asset_repository.get(asset_id).ok_or_else(|| { AccountError::ValidationError { info: format!( diff --git a/core/station/impl/src/services/address_book.rs b/core/station/impl/src/services/address_book.rs index 3664f1998..eca4df689 100644 --- a/core/station/impl/src/services/address_book.rs +++ b/core/station/impl/src/services/address_book.rs @@ -87,6 +87,7 @@ impl AddressBookService { addresses: input.addresses, blockchain: input.blockchain, labels: input.labels, + address_formats: input.address_formats, }); Ok(paginated_items(PaginatedItemsArgs { diff --git a/core/station/impl/src/services/asset.rs b/core/station/impl/src/services/asset.rs index f56334571..be07c252f 100644 --- a/core/station/impl/src/services/asset.rs +++ b/core/station/impl/src/services/asset.rs @@ -84,10 +84,6 @@ impl AssetService { asset.symbol = symbol; } - if let Some(decimals) = input.decimals { - asset.decimals = decimals; - } - if let Some(change_metadata) = input.change_metadata { asset.metadata.change(change_metadata); } @@ -227,7 +223,6 @@ mod tests { asset_id: mock_asset.id, name: Some("Internet Computer".to_string()), symbol: Some("ICP".to_string()), - decimals: Some(8), change_metadata: None, blockchain: None, standards: None, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9cc5e43e8..4fe019342 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,26 +60,29 @@ importers: apps/wallet: dependencies: '@dfinity/agent': - specifier: 2.1.2 - version: 2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2) + specifier: 1.4.0 + version: 1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0) '@dfinity/auth-client': - specifier: 2.1.2 - version: 2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/identity@2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@peculiar/webcrypto@1.4.3))(@dfinity/principal@2.1.2) + specifier: 1.4.0 + version: 1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/identity@1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@peculiar/webcrypto@1.4.3))(@dfinity/principal@1.4.0) '@dfinity/candid': - specifier: 2.1.2 - version: 2.1.2(@dfinity/principal@2.1.2) + specifier: 1.4.0 + version: 1.4.0(@dfinity/principal@1.4.0) '@dfinity/didc': specifier: 0.0.2 version: 0.0.2 '@dfinity/identity': - specifier: 2.1.2 - version: 2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@peculiar/webcrypto@1.4.3) + specifier: 1.4.0 + version: 1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@peculiar/webcrypto@1.4.3) '@dfinity/ledger-icrc': - specifier: 2.6.1 - version: 2.6.1(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@dfinity/utils@2.5.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)) + specifier: 2.3.3 + version: 2.3.3(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@dfinity/utils@2.3.1(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)) '@dfinity/principal': - specifier: 2.1.2 - version: 2.1.2 + specifier: 1.4.0 + version: 1.4.0 + '@dfinity/utils': + specifier: 2.3.1 + version: 2.3.1(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0) '@mdi/font': specifier: 7.4.47 version: 7.4.47 @@ -821,29 +824,18 @@ packages: '@dfinity/candid': ^1.4.0 '@dfinity/principal': ^1.4.0 - '@dfinity/agent@2.1.2': - resolution: {integrity: sha512-UAXf6uXovhBlSp245RWlA21zcCavy+vVUvKVQUpesk1gLJpJlvsCE6hYOwTeFZAP+bjmPi0Tl7cx8DT2KM4eDQ==} + '@dfinity/auth-client@1.4.0': + resolution: {integrity: sha512-9ImeOAw61SQvHJ+w4RHIuKKUL2xAQDLoce+JhmH3DbJuVvNbZIM5xMW8gHTZVlXaMw3Vhip+a1DPJIGy95r9pA==} peerDependencies: - '@dfinity/candid': ^2.1.2 - '@dfinity/principal': ^2.1.2 - - '@dfinity/auth-client@2.1.2': - resolution: {integrity: sha512-3wIbap6NQi+6z/o+kEFfOQmWuIz94/j1efVlkBtLO0IWqC5NZqoMppwANZZCkENeMvI0krhqH3asQvediWKIsg==} - peerDependencies: - '@dfinity/agent': ^2.1.2 - '@dfinity/identity': ^2.1.2 - '@dfinity/principal': ^2.1.2 + '@dfinity/agent': ^1.4.0 + '@dfinity/identity': ^1.4.0 + '@dfinity/principal': ^1.4.0 '@dfinity/candid@1.4.0': resolution: {integrity: sha512-PsTJVn63ZM4A/6Xs5coI0zMFevSwJ8hcyh38LdH/92n6wi9UOTis1yc4qL5MZvvRCUAD0c3rVjELL+49E9sPyA==} peerDependencies: '@dfinity/principal': ^1.4.0 - '@dfinity/candid@2.1.2': - resolution: {integrity: sha512-do69J9iahW2tlmbPdbmc8MDhi5cfIQyTcAlYqaSOOAyg+Kp8beCnW7mletXVfx30dyVlpkyCrYOXhbpQuSCKtw==} - peerDependencies: - '@dfinity/principal': ^2.1.2 - '@dfinity/didc@0.0.2': resolution: {integrity: sha512-ISsRNtbBdRnv98K9fucgSOrsMv6fJ311zyOWU1MYGWyV/IGWT6q7Xh1vcASZ0BcAiDITxinSTjgB8mUlDjpHcQ==} engines: {node: ^20, npm: please use pnpm, pnpm: ^9, yarn: please use pnpm} @@ -855,33 +847,23 @@ packages: '@dfinity/principal': ^1.4.0 '@peculiar/webcrypto': ^1.4.0 - '@dfinity/identity@2.1.2': - resolution: {integrity: sha512-LgskXJzyqm1UVsobAkF8bL1/SdLKFYW2kTIsKw7UOhuBy/COpnf3HZYmKeFCnxvharyIyq23W3WBhIpu9FeAvw==} - peerDependencies: - '@dfinity/agent': ^2.1.2 - '@dfinity/principal': ^2.1.2 - '@peculiar/webcrypto': ^1.4.0 - - '@dfinity/ledger-icrc@2.6.1': - resolution: {integrity: sha512-fsCC01JHDIA+2l7CRll44yB5/OF2qj3Gz7xE10SW7V80elYULfa98w9ks12dqxGh62+62btxujU7ylluTgugyg==} + '@dfinity/ledger-icrc@2.3.3': + resolution: {integrity: sha512-ASF9A/FcyHlEsFVENEZ1/f/PFcdvtEg75zD70zL/n7FUSN+3I8c82tbt5TunraRCGBQjDgBigUoRY2+k5J18rQ==} peerDependencies: - '@dfinity/agent': ^2.0.0 - '@dfinity/candid': ^2.0.0 - '@dfinity/principal': ^2.0.0 - '@dfinity/utils': ^2.5.2 + '@dfinity/agent': ^1.3.0 + '@dfinity/candid': ^1.3.0 + '@dfinity/principal': ^1.3.0 + '@dfinity/utils': ^2.3.1 '@dfinity/principal@1.4.0': resolution: {integrity: sha512-SuTBVlc71ub89ji0WN5/T100zUG2uIMn5x4+We4vS4nJ0R3/Xt89XJsHepjd5SQTSQPOvP7eQ+S8cQKWRz/RkA==} - '@dfinity/principal@2.1.2': - resolution: {integrity: sha512-L3Y0nDjquqNFseM2Gx5fI4GOUKjjezFr9/6ZjSwAFeDeb4Ubqld4ZKL3FEzv4QKNbfZgCx19b7UXi+OdmLhi4w==} - - '@dfinity/utils@2.5.2': - resolution: {integrity: sha512-QSW7t8kcLj0s/gL4NbYqr+Pqr3e2QhFn2JriwcghuflhwrYet1y23ANyM4EwSUeDAUR/OQXR86e4MfWkGMttAg==} + '@dfinity/utils@2.3.1': + resolution: {integrity: sha512-FvMBwlKBJGJhugGRn13U0Jvfldu01P2QZXDqogkWTHnQs+IJ8N1sVLQ8DQaT+bnOaT5Ii8kEes0ecaMaeTdHgw==} peerDependencies: - '@dfinity/agent': ^2.0.0 - '@dfinity/candid': ^2.0.0 - '@dfinity/principal': ^2.0.0 + '@dfinity/agent': ^1.3.0 + '@dfinity/candid': ^1.3.0 + '@dfinity/principal': ^1.3.0 '@emnapi/core@1.3.0': resolution: {integrity: sha512-9hRqVlhwqBqCoToZ3hFcNVqL+uyHV06Y47ax4UB8L6XgVRqYz7MFnfessojo6+5TK89pKwJnpophwjTMOeKI9Q==} @@ -4754,32 +4736,17 @@ snapshots: buffer: 6.0.3 simple-cbor: 0.4.1 - '@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)': - dependencies: - '@dfinity/candid': 2.1.2(@dfinity/principal@2.1.2) - '@dfinity/principal': 2.1.2 - '@noble/curves': 1.4.0 - '@noble/hashes': 1.4.0 - base64-arraybuffer: 0.2.0 - borc: 2.1.2 - buffer: 6.0.3 - simple-cbor: 0.4.1 - - '@dfinity/auth-client@2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/identity@2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@peculiar/webcrypto@1.4.3))(@dfinity/principal@2.1.2)': + '@dfinity/auth-client@1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/identity@1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@peculiar/webcrypto@1.4.3))(@dfinity/principal@1.4.0)': dependencies: - '@dfinity/agent': 2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2) - '@dfinity/identity': 2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@peculiar/webcrypto@1.4.3) - '@dfinity/principal': 2.1.2 + '@dfinity/agent': 1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0) + '@dfinity/identity': 1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@peculiar/webcrypto@1.4.3) + '@dfinity/principal': 1.4.0 idb: 7.1.1 '@dfinity/candid@1.4.0(@dfinity/principal@1.4.0)': dependencies: '@dfinity/principal': 1.4.0 - '@dfinity/candid@2.1.2(@dfinity/principal@2.1.2)': - dependencies: - '@dfinity/principal': 2.1.2 - '@dfinity/didc@0.0.2': {} '@dfinity/identity@1.4.0(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@peculiar/webcrypto@1.4.3)': @@ -4791,35 +4758,22 @@ snapshots: '@peculiar/webcrypto': 1.4.3 borc: 2.1.2 - '@dfinity/identity@2.1.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@peculiar/webcrypto@1.4.3)': + '@dfinity/ledger-icrc@2.3.3(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)(@dfinity/utils@2.3.1(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))': dependencies: - '@dfinity/agent': 2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2) - '@dfinity/principal': 2.1.2 - '@noble/curves': 1.4.0 - '@noble/hashes': 1.4.0 - '@peculiar/webcrypto': 1.4.3 - borc: 2.1.2 - - '@dfinity/ledger-icrc@2.6.1(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)(@dfinity/utils@2.5.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))': - dependencies: - '@dfinity/agent': 2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2) - '@dfinity/candid': 2.1.2(@dfinity/principal@2.1.2) - '@dfinity/principal': 2.1.2 - '@dfinity/utils': 2.5.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2) + '@dfinity/agent': 1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0) + '@dfinity/candid': 1.4.0(@dfinity/principal@1.4.0) + '@dfinity/principal': 1.4.0 + '@dfinity/utils': 2.3.1(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0) '@dfinity/principal@1.4.0': dependencies: '@noble/hashes': 1.4.0 - '@dfinity/principal@2.1.2': + '@dfinity/utils@2.3.1(@dfinity/agent@1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0))(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0)': dependencies: - '@noble/hashes': 1.4.0 - - '@dfinity/utils@2.5.2(@dfinity/agent@2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2))(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2)': - dependencies: - '@dfinity/agent': 2.1.2(@dfinity/candid@2.1.2(@dfinity/principal@2.1.2))(@dfinity/principal@2.1.2) - '@dfinity/candid': 2.1.2(@dfinity/principal@2.1.2) - '@dfinity/principal': 2.1.2 + '@dfinity/agent': 1.4.0(@dfinity/candid@1.4.0(@dfinity/principal@1.4.0))(@dfinity/principal@1.4.0) + '@dfinity/candid': 1.4.0(@dfinity/principal@1.4.0) + '@dfinity/principal': 1.4.0 '@emnapi/core@1.3.0': dependencies: diff --git a/tests/integration/src/address_book_tests.rs b/tests/integration/src/address_book_tests.rs index c0fbaee9f..3a28a0541 100644 --- a/tests/integration/src/address_book_tests.rs +++ b/tests/integration/src/address_book_tests.rs @@ -132,6 +132,7 @@ fn address_book_entry_lifecycle() { addresses: None, ids: None, paginate: None, + address_formats: None, }; let res: (Result,) = update_candid_as( &env, @@ -205,6 +206,7 @@ fn address_book_entry_lifecycle() { addresses: None, ids: None, paginate: None, + address_formats: None, }; let res: (Result,) = update_candid_as( &env, diff --git a/tests/integration/src/asset_tests.rs b/tests/integration/src/asset_tests.rs index 0bc922850..5b0fdf491 100644 --- a/tests/integration/src/asset_tests.rs +++ b/tests/integration/src/asset_tests.rs @@ -1,3 +1,5 @@ +use candid::Principal; + use crate::{ setup::{setup_new_env, WALLET_ADMIN_USER}, test_data::{ @@ -93,8 +95,29 @@ fn asset_permission_test() { let user = add_user(&env, canister_ids.station, WALLET_ADMIN_USER, vec![]); list_assets(&env, canister_ids.station, user.identities[0]) - .expect_err("User should not be able to list assets"); + .expect("Station user should be able to list assets") + .0 + .expect("Station user should be able to list assets"); + + list_assets(&env, canister_ids.station, Principal::anonymous()) + .expect_err("Unauthenticated user should not be able to list assets"); - get_asset(&env, canister_ids.station, user.identities[0], asset.id) - .expect_err("User should not be able to get asset"); + get_asset( + &env, + canister_ids.station, + Principal::anonymous(), + asset.id.clone(), + ) + .expect_err("Unauthenticated user should not be able to get asset"); + + list_assets(&env, canister_ids.station, Principal::from_slice(&[0; 29])) + .expect_err("Unauthorized user should not be able to list assets"); + + get_asset( + &env, + canister_ids.station, + Principal::from_slice(&[0; 29]), + asset.id, + ) + .expect_err("Unauthorized user should not be able to get asset"); } diff --git a/tests/integration/src/migration_tests.rs b/tests/integration/src/migration_tests.rs index 047e4dac2..e51fa12e0 100644 --- a/tests/integration/src/migration_tests.rs +++ b/tests/integration/src/migration_tests.rs @@ -388,6 +388,7 @@ fn assert_can_list_address_book_entries( blockchain: None, labels: None, addresses: None, + address_formats: None, ids: None, paginate: Some(station_api::PaginationInput { offset: Some(0), diff --git a/tests/integration/src/test_data/asset.rs b/tests/integration/src/test_data/asset.rs index 7d3a19609..d6a31e1ff 100644 --- a/tests/integration/src/test_data/asset.rs +++ b/tests/integration/src/test_data/asset.rs @@ -66,7 +66,6 @@ pub fn edit_asset_name( blockchain: None, standards: None, symbol: None, - decimals: None, change_metadata: None, }), );