Skip to content

Commit

Permalink
Add filterAddress() method to Motoko backend (#54)
Browse files Browse the repository at this point in the history
* Progress

* Add 'filteredAddresses' state

* Pass caller to core

* Filter addresses from 'getNfts()'

* Add access control to 'filterAddress()'

* Filter addresses from public history

* Refactor 'filterAddress(Text)' -> 'setAddressFiltered(Text, Bool)'

* Implement filtered=false functionality
  • Loading branch information
rvanasa committed Aug 25, 2023
1 parent 1a038de commit 2b9ccf4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
13 changes: 12 additions & 1 deletion canisters/backend/Core.mo
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ module {
};

public func getNfts(caller : Principal) : [Types.Nft.Nft] {
let nfts = Iter.mapFilter<Types.PublicEvent, Types.Nft.Nft>(
let nfts = Iter.filterMap<Types.PublicEvent, Types.Nft.Nft>(
state.getPublicHistory(),
func(e : Types.PublicEvent) : ?Types.Nft.Nft {
switch (e) {
Expand All @@ -105,6 +105,17 @@ module {
Iter.toArray(nfts);
};

public func setAddressFiltered(caller : Principal, address : Types.Address.Address, filtered : Bool) : async Bool {
assert caller == installer;
let log = logger.Begin(caller, #setAddressFiltered(address, filtered));
if (filtered) {
state.filteredAddresses.put(address);
} else {
state.filteredAddresses.remove(address);
};
log.okWith(true);
};

public func getPublicHistory(caller : Principal) : [Types.PublicEvent] {
Iter.toArray(state.getPublicHistory());
};
Expand Down
1 change: 1 addition & 0 deletions canisters/backend/History.mo
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module {
#connectEthWallet : (Types.EthWallet, Types.SignedPrincipal);
#isNftOwned : Types.Nft.Nft;
#addNfts : [Types.Nft.Nft];
#setAddressFiltered : (Types.Address.Address, Bool);
};

public type Response = {
Expand Down
5 changes: 5 additions & 0 deletions canisters/backend/Main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ shared ({ caller = installer }) actor class Main() {
core.getNfts(caller);
};

/// Hide or show all NFTs with the given smart contract or wallet address.
public shared ({ caller }) func setAddressFiltered(address : Types.Address.Address, filtered : Bool) : async Bool {
await core.setAddressFiltered(caller, address, filtered);
};

/// Retrieve the full log for this canister.
public query ({ caller }) func getHistory() : async ?[History.Event] {
core.getHistory(caller);
Expand Down
20 changes: 18 additions & 2 deletions canisters/backend/State.mo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Principal "mo:base/Principal";
import Int "mo:base/Int";
import Seq "mo:sequence/Sequence";
import Stream "mo:sequence/Stream";
import Iter_ "lib/IterMore";
import Relate "lib/Relate";
import System "lib/System";

Expand Down Expand Up @@ -38,8 +39,8 @@ module {
//
principals : Relate.Stable.Map<Principal, CreateSuccess>;
ethWallets : Relate.Stable.Map<EthWallet, CreateSuccess>;

ethNfts : Relate.Stable.Map<NftId, Nft>;
filteredAddresses : Relate.Stable.Map<Address.Address, ()>;

//
// Relations
Expand All @@ -57,6 +58,7 @@ module {
principals = Relate.Stable.emptyMap();
ethWallets = Relate.Stable.emptyMap();
ethNfts = Relate.Stable.emptyMap();
filteredAddresses = Relate.Stable.emptyMap();

walletSignsPrincipal = Relate.Stable.emptyTernRel();
walletOwnsNft = Relate.Stable.emptyTernRel();
Expand All @@ -80,6 +82,8 @@ module {

public let ethNfts = Relate.OO.Map<NftId, Nft>(state.ethNfts, NftId.hash, NftId.equal);

public let filteredAddresses = Relate.OO.UnRel<Address.Address>(state.filteredAddresses, Address.hash, Address.equal);

public let walletSignsPrincipal = Relate.OO.TernRel<EthWallet, Principal, SignatureCheckSuccess>(
state.walletSignsPrincipal,
(Address.hash, Principal.hash),
Expand Down Expand Up @@ -142,7 +146,19 @@ module {
};

public func getPublicHistory() : Iter.Iter<Types.PublicEvent> {
Seq.iter(state.publicHistory.events, #bwd);
Iter_.filterMap<Types.PublicEvent, Types.PublicEvent>(
Seq.iter(state.publicHistory.events, #bwd),
func(e : Types.PublicEvent) : ?Types.PublicEvent {
switch (e) {
case (#addNft(e)) {
if (
not filteredAddresses.has(e.nft.contract) and not filteredAddresses.has(e.nft.owner)
) ? #addNft(e) else null;
};
case (e) ?e;
};
},
);
};

};
Expand Down
2 changes: 1 addition & 1 deletion canisters/backend/lib/IterMore.mo
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ module {
};
};

public func mapFilter<X, Y>(xs : Iter<X>, f : X -> ?Y) : Iter<Y> {
public func filterMap<X, Y>(xs : Iter<X>, f : X -> ?Y) : Iter<Y> {
object {
public func next() : ?Y {
loop {
Expand Down

0 comments on commit 2b9ccf4

Please sign in to comment.