Skip to content

Commit

Permalink
Merge pull request #81 from arkprotocol/cw721_admin
Browse files Browse the repository at this point in the history
new CW721_ADMIN store
  • Loading branch information
taitruong authored Jan 23, 2024
2 parents f1dfefc + b5c4acb commit 09da354
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 70 deletions.
23 changes: 19 additions & 4 deletions contracts/sg-ics721/src/testing/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ impl Test {
false => None,
};

let admin = admin_and_pauser
.clone()
.map(|p| app.api().addr_make(&p).to_string());
let ics721 = app
.instantiate_contract(
ics721_id,
Expand All @@ -346,9 +349,8 @@ impl Test {
cw721_base_code_id: source_cw721_id,
incoming_proxy,
outgoing_proxy,
pauser: admin_and_pauser
.clone()
.map(|p| app.api().addr_make(&p).to_string()),
pauser: admin.clone(),
cw721_admin: admin,
},
&[],
"sg-ics721",
Expand Down Expand Up @@ -452,6 +454,13 @@ impl Test {
.unwrap()
}

fn query_cw721_admin(&mut self) -> Option<Addr> {
self.app
.wrap()
.query_wasm_smart(self.ics721.clone(), &QueryMsg::Cw721Admin {})
.unwrap()
}

fn query_nft_contracts(&mut self) -> Vec<(String, Addr)> {
self.app
.wrap()
Expand Down Expand Up @@ -2337,6 +2346,7 @@ fn test_pause() {
incoming_proxy: None,
outgoing_proxy: None,
cw721_base_code_id: None,
cw721_admin: None,
})
.unwrap(),
}
Expand Down Expand Up @@ -2378,9 +2388,10 @@ fn test_migration() {
assert_eq!(cw721_code_id, test.source_cw721_id);

// migrate changes
let admin = test.app.api().addr_make(ICS721_ADMIN_AND_PAUSER);
test.app
.execute(
test.app.api().addr_make(ICS721_ADMIN_AND_PAUSER),
admin.clone(),
WasmMsg::Migrate {
contract_addr: test.ics721.to_string(),
new_code_id: test.ics721_id,
Expand All @@ -2389,6 +2400,7 @@ fn test_migration() {
incoming_proxy: None,
outgoing_proxy: None,
cw721_base_code_id: Some(12345678),
cw721_admin: Some(admin.to_string()),
})
.unwrap(),
}
Expand All @@ -2402,6 +2414,7 @@ fn test_migration() {
assert!(proxy.is_none());
let cw721_code_id = test.query_cw721_id();
assert_eq!(cw721_code_id, 12345678);
assert_eq!(test.query_cw721_admin(), Some(admin),);

// migrate without changing code id
test.app
Expand All @@ -2415,6 +2428,7 @@ fn test_migration() {
incoming_proxy: None,
outgoing_proxy: None,
cw721_base_code_id: None,
cw721_admin: Some("".to_string()),
})
.unwrap(),
}
Expand All @@ -2428,4 +2442,5 @@ fn test_migration() {
assert!(proxy.is_none());
let cw721_code_id = test.query_cw721_id();
assert_eq!(cw721_code_id, 12345678);
assert_eq!(test.query_cw721_admin(), None,);
}
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
set dotenv-load

platform := if arch() =~ "aarch64" {"linux/arm64"} else {"linux/amd64"}
image := if arch() =~ "aarch64" {"cosmwasm/workspace-optimizer-arm64:0.14.0"} else {"cosmwasm/workspace-optimizer:0.14.0"}
image := if arch() =~ "aarch64" {"cosmwasm/workspace-optimizer-arm64:0.15.0"} else {"cosmwasm/workspace-optimizer:0.15.0"}

alias log := optimize-watch

Expand Down
71 changes: 46 additions & 25 deletions packages/ics721/schema/ics721.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
"cw721_base_code_id"
],
"properties": {
"cw721_admin": {
"description": "The admin address for instantiating new cw721 contracts. In case of None, contract is immutable.",
"type": [
"string",
"null"
]
},
"cw721_base_code_id": {
"description": "Code ID of cw721-ics contract. A new cw721-ics will be instantiated for each new IBCd NFT classID.\n\nNOTE: this _must_ correspond to the cw721-base contract. Using a regular cw721 may cause the ICS 721 interface implemented by this contract to stop working, and IBCd away NFTs to be unreturnable as cw721 does not have a mint method in the spec.",
"type": "integer",
Expand Down Expand Up @@ -167,31 +174,6 @@
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"receive_proxy_nft"
],
"properties": {
"receive_proxy_nft": {
"type": "object",
"required": [
"eyeball",
"msg"
],
"properties": {
"eyeball": {
"type": "string"
},
"msg": {
"$ref": "#/definitions/Cw721ReceiveMsg"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
Expand Down Expand Up @@ -921,6 +903,20 @@
},
"additionalProperties": false
},
{
"description": "Gets the admin address for instantiating new cw721 contracts. In case of None, contract is immutable.",
"type": "object",
"required": [
"cw721_admin"
],
"properties": {
"cw721_admin": {
"type": "object",
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "Gets a list of classID as key (from NonFungibleTokenPacketData) and cw721 contract as value (instantiated for that classID).",
"type": "object",
Expand Down Expand Up @@ -1129,6 +1125,31 @@
}
}
},
"cw721_admin": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Nullable_Nullable_Addr",
"anyOf": [
{
"anyOf": [
{
"$ref": "#/definitions/Addr"
},
{
"type": "null"
}
]
},
{
"type": "null"
}
],
"definitions": {
"Addr": {
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
"type": "string"
}
}
},
"cw721_code_id": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "uint64",
Expand Down
25 changes: 0 additions & 25 deletions packages/ics721/schema/raw/execute.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,6 @@
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"receive_proxy_nft"
],
"properties": {
"receive_proxy_nft": {
"type": "object",
"required": [
"eyeball",
"msg"
],
"properties": {
"eyeball": {
"type": "string"
},
"msg": {
"$ref": "#/definitions/Cw721ReceiveMsg"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
Expand Down
7 changes: 7 additions & 0 deletions packages/ics721/schema/raw/instantiate.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
"cw721_base_code_id"
],
"properties": {
"cw721_admin": {
"description": "The admin address for instantiating new cw721 contracts. In case of None, contract is immutable.",
"type": [
"string",
"null"
]
},
"cw721_base_code_id": {
"description": "Code ID of cw721-ics contract. A new cw721-ics will be instantiated for each new IBCd NFT classID.\n\nNOTE: this _must_ correspond to the cw721-base contract. Using a regular cw721 may cause the ICS 721 interface implemented by this contract to stop working, and IBCd away NFTs to be unreturnable as cw721 does not have a mint method in the spec.",
"type": "integer",
Expand Down
14 changes: 14 additions & 0 deletions packages/ics721/schema/raw/query.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,20 @@
},
"additionalProperties": false
},
{
"description": "Gets the admin address for instantiating new cw721 contracts. In case of None, contract is immutable.",
"type": "object",
"required": [
"cw721_admin"
],
"properties": {
"cw721_admin": {
"type": "object",
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "Gets a list of classID as key (from NonFungibleTokenPacketData) and cw721 contract as value (instantiated for that classID).",
"type": "object",
Expand Down
25 changes: 25 additions & 0 deletions packages/ics721/schema/raw/response_to_cw721_admin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Nullable_Nullable_Addr",
"anyOf": [
{
"anyOf": [
{
"$ref": "#/definitions/Addr"
},
{
"type": "null"
}
]
},
{
"type": "null"
}
],
"definitions": {
"Addr": {
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
"type": "string"
}
}
}
48 changes: 43 additions & 5 deletions packages/ics721/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ use crate::{
},
msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg},
state::{
CollectionData, UniversalAllNftInfoResponse, CLASS_ID_TO_CLASS, CLASS_ID_TO_NFT_CONTRACT,
CW721_CODE_ID, INCOMING_PROXY, NFT_CONTRACT_TO_CLASS_ID, OUTGOING_CLASS_TOKEN_TO_CHANNEL,
OUTGOING_PROXY, PO, TOKEN_METADATA,
CollectionData, UniversalAllNftInfoResponse, ADMIN_USED_FOR_CW721, CLASS_ID_TO_CLASS,
CLASS_ID_TO_NFT_CONTRACT, CW721_CODE_ID, INCOMING_PROXY, NFT_CONTRACT_TO_CLASS_ID,
OUTGOING_CLASS_TOKEN_TO_CHANNEL, OUTGOING_PROXY, PO, TOKEN_METADATA,
},
token_types::{VoucherCreation, VoucherRedemption},
ContractError,
Expand Down Expand Up @@ -62,10 +62,23 @@ where
));
}

ADMIN_USED_FOR_CW721.save(
deps.storage,
&msg.cw721_admin
.as_ref()
.map(|h| deps.api.addr_validate(h))
.transpose()?,
)?;

Ok(Response::default()
.add_submessages(proxies_instantiate)
.add_attribute("method", "instantiate")
.add_attribute("cw721_code_id", msg.cw721_base_code_id.to_string()))
.add_attribute("cw721_code_id", msg.cw721_base_code_id.to_string())
.add_attribute(
"cw721_admin",
msg.cw721_admin
.map_or_else(|| "immutable".to_string(), |or| or),
))
}

fn execute(
Expand Down Expand Up @@ -323,9 +336,12 @@ where
CLASS_ID_TO_NFT_CONTRACT.save(deps.storage, class_id.clone(), &cw721_addr)?;
NFT_CONTRACT_TO_CLASS_ID.save(deps.storage, cw721_addr, &class_id)?;

let admin = ADMIN_USED_FOR_CW721
.load(deps.storage)?
.map(|a| a.to_string());
let message = SubMsg::<T>::reply_on_success(
WasmMsg::Instantiate2 {
admin: None,
admin,
code_id: cw721_code_id,
msg: self.init_msg(deps.as_ref(), &env, &class)?,
funds: vec![],
Expand Down Expand Up @@ -471,6 +487,7 @@ where
incoming_proxy,
outgoing_proxy,
cw721_base_code_id,
cw721_admin,
} => {
// disables incoming proxy if none is provided!
INCOMING_PROXY.save(
Expand All @@ -492,6 +509,14 @@ where
if let Some(cw721_base_code_id) = cw721_base_code_id {
CW721_CODE_ID.save(deps.storage, &cw721_base_code_id)?;
}
if let Some(cw721_admin) = cw721_admin.clone() {
if cw721_admin.is_empty() {
ADMIN_USED_FOR_CW721.save(deps.storage, &None)?;
} else {
ADMIN_USED_FOR_CW721
.save(deps.storage, &Some(deps.api.addr_validate(&cw721_admin)?))?;
}
}
Ok(Response::default()
.add_attribute("method", "migrate")
.add_attribute("pauser", pauser.map_or_else(|| "none".to_string(), |or| or))
Expand All @@ -506,6 +531,19 @@ where
.add_attribute(
"cw721_base_code_id",
cw721_base_code_id.map_or_else(|| "none".to_string(), |or| or.to_string()),
)
.add_attribute(
"cw721_admin",
cw721_admin.map_or_else(
|| "none".to_string(),
|or| {
if or.is_empty() {
"immutable".to_string()
} else {
or
}
},
),
))
}
}
Expand Down
Loading

0 comments on commit 09da354

Please sign in to comment.