Skip to content

Commit

Permalink
Matrix ADO (#539)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdjakovic0920 authored Dec 10, 2024
1 parent 0b6042f commit e2348ec
Show file tree
Hide file tree
Showing 15 changed files with 970 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- Added optional config for Send in Splitter contracts [(#686)](https://github.com/andromedaprotocol/andromeda-core/pull/686)

- Matrix ADO [(#539)](https://github.com/andromedaprotocol/andromeda-core/pull/539)
- Added Distance ADO [(#570)](https://github.com/andromedaprotocol/andromeda-core/pull/570)

### Changed
Expand Down
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions contracts/math/andromeda-matrix/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[alias]
wasm = "build --release --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --example schema"
40 changes: 40 additions & 0 deletions contracts/math/andromeda-matrix/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[package]
name = "andromeda-matrix"
version = "0.1.0-beta"
edition = "2021"
rust-version = "1.75.0"

exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"contract.wasm",
"hash.txt",
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]

[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
testing = ["cw-multi-test", "andromeda-testing"]

[dependencies]
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw-storage-plus = { workspace = true }
cw-utils = { workspace = true }
cw20 = { workspace = true }


andromeda-std = { workspace = true, features = ["rates"] }
andromeda-math = { workspace = true }


[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
cw-orch = { workspace = true }
cw-multi-test = { workspace = true, optional = true }
andromeda-testing = { workspace = true, optional = true }
10 changes: 10 additions & 0 deletions contracts/math/andromeda-matrix/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use andromeda_math::matrix::{ExecuteMsg, InstantiateMsg, QueryMsg};
use cosmwasm_schema::write_api;
fn main() {
write_api! {
instantiate: InstantiateMsg,
query: QueryMsg,
execute: ExecuteMsg,

}
}
240 changes: 240 additions & 0 deletions contracts/math/andromeda-matrix/src/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, Storage};

use andromeda_math::matrix::{ExecuteMsg, InstantiateMsg, QueryMsg};
use andromeda_math::matrix::{GetMatrixResponse, Matrix};
use andromeda_std::{
ado_base::{
permissioning::{LocalPermission, Permission},
InstantiateMsg as BaseInstantiateMsg, MigrateMsg,
},
ado_contract::ADOContract,
amp::AndrAddr,
common::{actions::call_action, context::ExecuteContext, encode_binary},
error::ContractError,
};

use cw_utils::nonpayable;

use crate::state::{DEFAULT_KEY, KEY_OWNER, MATRIX};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:andromeda-matrix";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

pub const STORE_MATRIX_ACTION: &str = "store_matrix";
pub const DELETE_MATRIX_ACTION: &str = "delete_matrix";

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
let resp = ADOContract::default().instantiate(
deps.storage,
env,
deps.api,
&deps.querier,
info,
BaseInstantiateMsg {
ado_type: CONTRACT_NAME.to_string(),
ado_version: CONTRACT_VERSION.to_string(),
kernel_address: msg.kernel_address,
owner: msg.owner,
},
)?;

if let Some(authorized_operator_addresses) = msg.authorized_operator_addresses {
if !authorized_operator_addresses.is_empty() {
ADOContract::default().permission_action(STORE_MATRIX_ACTION, deps.storage)?;
ADOContract::default().permission_action(DELETE_MATRIX_ACTION, deps.storage)?;
}

for address in authorized_operator_addresses {
let addr = address.get_raw_address(&deps.as_ref())?;
ADOContract::set_permission(
deps.storage,
STORE_MATRIX_ACTION,
addr.clone(),
Permission::Local(LocalPermission::Whitelisted(None)),
)?;
ADOContract::set_permission(
deps.storage,
DELETE_MATRIX_ACTION,
addr.clone(),
Permission::Local(LocalPermission::Whitelisted(None)),
)?;
}
}

Ok(resp)
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
let ctx = ExecuteContext::new(deps, info, env);
match msg {
ExecuteMsg::AMPReceive(pkt) => {
ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute)
}
_ => handle_execute(ctx, msg),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary, ContractError> {
match msg {
QueryMsg::GetMatrix { key } => encode_binary(&get_matrix(deps.storage, key)?),
QueryMsg::AllKeys {} => encode_binary(&all_keys(deps.storage)?),
QueryMsg::OwnerKeys { owner } => encode_binary(&owner_keys(&deps, owner)?),
_ => ADOContract::default().query(deps, env, msg),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION)
}

pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result<Response, ContractError> {
let action_response = call_action(
&mut ctx.deps,
&ctx.info,
&ctx.env,
&ctx.amp_ctx,
msg.as_ref(),
)?;

let res = match msg.clone() {
ExecuteMsg::StoreMatrix { key, data } => store_matrix(ctx, key, data),
ExecuteMsg::DeleteMatrix { key } => delete_matrix(ctx, key),
_ => ADOContract::default().execute(ctx, msg),
}?;

Ok(res
.add_submessages(action_response.messages)
.add_attributes(action_response.attributes)
.add_events(action_response.events))
}

/// ============================== Execution Functions ============================== ///
pub fn store_matrix(
mut ctx: ExecuteContext,
key: Option<String>,
data: Matrix,
) -> Result<Response, ContractError> {
nonpayable(&ctx.info)?;
let sender = ctx.info.sender.clone();

ADOContract::default().is_permissioned(
ctx.deps.branch(),
ctx.env.clone(),
STORE_MATRIX_ACTION,
sender.clone(),
)?;

// Validate the data
data.validate_matrix()?;

let key: &str = get_key_or_default(&key);

MATRIX.update::<_, StdError>(ctx.deps.storage, key, |old| match old {
Some(_) => Ok(data.clone()),
None => Ok(data.clone()),
})?;
// Update the owner of the key
KEY_OWNER.update::<_, StdError>(ctx.deps.storage, key, |old| match old {
Some(old) => Ok(old),
None => Ok(sender.clone()),
})?;

let response = Response::new()
.add_attribute("method", "store_matrix")
.add_attribute("sender", sender)
.add_attribute("key", key)
.add_attribute("data", format!("{data:?}"));

Ok(response)
}

pub fn delete_matrix(
mut ctx: ExecuteContext,
key: Option<String>,
) -> Result<Response, ContractError> {
nonpayable(&ctx.info)?;
let sender = ctx.info.sender;

ADOContract::default().is_permissioned(
ctx.deps.branch(),
ctx.env.clone(),
DELETE_MATRIX_ACTION,
sender.clone(),
)?;

let key = get_key_or_default(&key);

MATRIX.remove(ctx.deps.storage, key);
KEY_OWNER.remove(ctx.deps.storage, key);
Ok(Response::new()
.add_attribute("method", "delete_matrix")
.add_attribute("sender", sender)
.add_attribute("key", key))
}

/// ============================== Query Functions ============================== ///
pub fn get_matrix(
storage: &dyn Storage,
key: Option<String>,
) -> Result<GetMatrixResponse, ContractError> {
let key = get_key_or_default(&key);
let data = MATRIX.load(storage, key)?;
Ok(GetMatrixResponse {
key: key.to_string(),
data,
})
}

pub fn all_keys(storage: &dyn Storage) -> Result<Vec<String>, ContractError> {
let keys = MATRIX
.keys(storage, None, None, cosmwasm_std::Order::Ascending)
.map(|key| key.unwrap())
.collect();
Ok(keys)
}

pub fn owner_keys(deps: &Deps, owner: AndrAddr) -> Result<Vec<String>, ContractError> {
let owner = owner.get_raw_address(deps)?;
let keys = KEY_OWNER
.range(deps.storage, None, None, cosmwasm_std::Order::Ascending)
.filter(|x| x.as_ref().unwrap().1 == owner)
.map(|key| key.unwrap().0)
.collect();
Ok(keys)
}

pub fn get_key_or_default(name: &Option<String>) -> &str {
match name {
None => DEFAULT_KEY,
Some(s) => s,
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
if msg.result.is_err() {
return Err(ContractError::Std(StdError::generic_err(
msg.result.unwrap_err(),
)));
}

Ok(Response::default())
}
6 changes: 6 additions & 0 deletions contracts/math/andromeda-matrix/src/interface.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use andromeda_math::matrix::{ExecuteMsg, InstantiateMsg, QueryMsg};
use andromeda_std::{ado_base::MigrateMsg, contract_interface, deploy::ADOMetadata};

pub const CONTRACT_ID: &str = "matrix";

contract_interface!(MatrixContract, CONTRACT_ID, "andromeda_matrix.wasm");
13 changes: 13 additions & 0 deletions contracts/math/andromeda-matrix/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pub mod contract;
pub mod state;

#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))]
pub mod mock;

#[cfg(test)]
mod testing;

#[cfg(not(target_arch = "wasm32"))]
mod interface;
#[cfg(not(target_arch = "wasm32"))]
pub use crate::interface::MatrixContract;
Loading

0 comments on commit e2348ec

Please sign in to comment.