Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: token erc721 uristorage #109

2 changes: 1 addition & 1 deletion cairo/src/contracts/client/router_component.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod RouterComponent {
}

#[embeddable_as(RouterImpl)]
impl Router<
pub impl Router<
TContractState,
+HasComponent<TContractState>,
+MailboxclientComponent::HasComponent<TContractState>,
Expand Down
10 changes: 6 additions & 4 deletions cairo/src/contracts/token/components/hyp_erc721_component.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use starknet::{ContractAddress, ClassHash};

#[starknet::interface]
pub trait IHypErc721<TState> {
fn initialize(ref self: TState, mint_amount: u256, name: ByteArray, symbol: ByteArray,);
fn initialize(ref self: TState, mint_amount: u256, name: ByteArray, symbol: ByteArray, base_uri: ByteArray);
}

#[starknet::component]
Expand All @@ -11,6 +11,7 @@ pub mod HypErc721Component {
MailboxclientComponent, MailboxclientComponent::MailboxClientInternalImpl,
MailboxclientComponent::MailboxClient
};
use hyperlane_starknet::contracts::token::components::token_router::{ TokenRouterComponent, TokenRouterComponent::TokenRouterHooksTrait as TokenRouterHooksTraits };
use openzeppelin::access::ownable::{
OwnableComponent, OwnableComponent::InternalImpl as OwnableInternalImpl
};
Expand All @@ -29,7 +30,7 @@ pub mod HypErc721Component {
struct Storage {}

#[embeddable_as(HypErc721Impl)]
impl HypErc721<
pub impl HypErc721<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
Expand All @@ -44,9 +45,10 @@ pub mod HypErc721Component {
mint_amount: u256,
name: ByteArray,
symbol: ByteArray,
base_uri: ByteArray
) {
let mut erc721_comp = get_dep_component_mut!(ref self, ERC721);
erc721_comp.initializer(name, symbol, "");
erc721_comp.initializer(name, symbol, base_uri);

let caller = starknet::get_caller_address();

Expand All @@ -59,7 +61,7 @@ pub mod HypErc721Component {
}

#[generate_trait]
impl HypErc721InternalImpl<
pub impl HypErc721InternalImpl<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
Expand Down
2 changes: 1 addition & 1 deletion cairo/src/contracts/token/components/token_router.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ pub mod TokenRouterComponent {
}

#[embeddable_as(TokenRouterImpl)]
impl TokenRouter<
pub impl TokenRouter<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
Expand Down
230 changes: 204 additions & 26 deletions cairo/src/contracts/token/extensions/hyp_erc721_URI_storage.cairo
Realkayzee marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,48 +1,226 @@
use starknet::ContractAddress;

#[starknet::interface]
pub trait IHypERC721URIStorage<TState> {
fn initialize(ref self: TState);
fn balance_of(self: @TState, account: u256) -> u256;
fn token_uri(self: @TState, token_id: u256) -> u256;
fn supports_interface(self: @TState, interface_id: u256) -> bool;
fn initialize(
ref self: TState,
_mint_amount: u256,
_name: ByteArray,
_symbol: ByteArray,
_hook: ContractAddress,
_interchainSecurityModule: ContractAddress,
owner: ContractAddress
);
}

#[starknet::interface]


#[starknet::contract]
pub mod HypERC721URIStorage {
use openzeppelin::access::ownable::OwnableComponent;
use hyperlane_starknet::contracts::client::mailboxclient_component::MailboxclientComponent;
use hyperlane_starknet::contracts::client::router_component::RouterComponent;
use hyperlane_starknet::contracts::client::gas_router_component::GasRouterComponent;
use hyperlane_starknet::contracts::token::components::token_router::{
TokenRouterComponent, TokenRouterComponent::TokenRouterHooksTrait,
TokenRouterComponent::MessageRecipientInternalHookImpl,
TokenRouterTransferRemoteHookDefaultImpl
};
use hyperlane_starknet::contracts::token::components::hyp_erc721_component::HypErc721Component;
use openzeppelin::token::erc721::{ERC721Component, ERC721Component::ERC721HooksTrait};
use openzeppelin::introspection::src5::SRC5Component;
use starknet::{ ContractAddress, get_caller_address };
use core::num::traits::Zero;
use alexandria_bytes::{ Bytes, BytesTrait };
use openzeppelin::upgrades::{interface::IUpgradeable, upgradeable::UpgradeableComponent};

component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
component!(path: MailboxclientComponent, storage: mailboxclient, event: MailboxclientEvent);
component!(path: RouterComponent, storage: router, event: RouterEvent);
component!(path: GasRouterComponent, storage: gas_router, event: GasRouterEvent);
component!(path: TokenRouterComponent, storage: token_router, event: TokenRouterEvent);
component!(path: HypErc721Component, storage: hyp_erc721, event: HypErc721Event);
component!(path: ERC721Component, storage: erc721, event: ERC721Event);
component!(path: SRC5Component, storage: src5, event: SRC5Event);
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);

// Ownable
#[abi(embed_v0)]
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

// MailboxClient
#[abi(embed_v0)]
impl MailboxClientImpl = MailboxclientComponent::MailboxClientImpl<ContractState>;
impl MailboxClientInternalImpl = MailboxclientComponent::MailboxClientInternalImpl<ContractState>;

//Router
#[abi(embed_v0)]
impl RouterImpl = RouterComponent::RouterImpl<ContractState>;
impl RouterInternalImpl = RouterComponent::RouterComponentInternalImpl<ContractState>;

// GasRouter
#[abi(embed_v0)]
impl GasRouterImpl = GasRouterComponent::GasRouterImpl<ContractState>;

// TokenRouter
#[abi(embed_v0)]
impl TokenRouterImpl = TokenRouterComponent::TokenRouterImpl<ContractState>;
impl TokenRouterInternalImpl = TokenRouterComponent::TokenRouterInternalImpl<ContractState>;

//HypERC721

Realkayzee marked this conversation as resolved.
Show resolved Hide resolved
impl HypErc721Impl = HypErc721Component::HypErc721Impl<ContractState>;
impl HypErc721InternalImpl = HypErc721Component::HypErc721InternalImpl<ContractState>;

//ERC721
#[abi(embed_v0)]
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;

impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;

#[storage]
struct Storage {
mailbox: u256,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
#[substorage(v0)]
mailboxclient: MailboxclientComponent::Storage,
#[substorage(v0)]
router: RouterComponent::Storage,
#[substorage(v0)]
gas_router: GasRouterComponent::Storage,
#[substorage(v0)]
token_router: TokenRouterComponent::Storage,
#[substorage(v0)]
hyp_erc721: HypErc721Component::Storage,
#[substorage(v0)]
erc721: ERC721Component::Storage,
#[substorage(v0)]
src5: SRC5Component::Storage,
#[substorage(v0)]
upgradeable: UpgradeableComponent::Storage,
}

fn constructor() {}
#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
OwnableEvent: OwnableComponent::Event,
#[flat]
MailboxclientEvent: MailboxclientComponent::Event,
#[flat]
RouterEvent: RouterComponent::Event,
#[flat]
GasRouterEvent: GasRouterComponent::Event,
#[flat]
TokenRouterEvent: TokenRouterComponent::Event,
#[flat]
ERC721Event: ERC721Component::Event,
#[flat]
SRC5Event: SRC5Component::Event,
#[flat]
HypErc721Event: HypErc721Component::Event,
#[flat]
UpgradeableEvent: UpgradeableComponent::Event,
}

impl HypERC721URIStorageImpl of super::IHypERC721URIStorage<ContractState> {
fn initialize(ref self: ContractState) {}
#[constructor]
fn constructor(
ref self: ContractState,
owner: ContractAddress,
mailbox: ContractAddress,
_mint_amount: u256,
_name: ByteArray,
_symbol: ByteArray,
_base_uri: ByteArray,
_hook: ContractAddress,
_interchainSecurityModule: ContractAddress,
) {
self.ownable.initializer(owner);
self.mailboxclient.initialize(mailbox, Option::Some(_hook), Option::Some(_interchainSecurityModule));
self.hyp_erc721.initialize(
_mint_amount,
_name,
_symbol,
_base_uri
)
}

fn balance_of(self: @ContractState, account: u256) -> u256 {
0
#[abi(embed_v0)]
impl HypErc721Upgradeable of IUpgradeable<ContractState> {
fn upgrade(ref self: ContractState, new_class_hash: starknet::ClassHash) {
self.ownable.assert_only_owner();
self.upgradeable.upgrade(new_class_hash);
}
}

fn token_uri(self: @ContractState, token_id: u256) -> u256 {
0
}
// #[generate_trait]
// impl InternalImpl of InternalTrait {
// fn transfer_from_sender(ref self: ContractState, token_id: u256) -> u256 {
// self.hyp_erc721.transfer_from_sender(token_id);
// token_id
// }

fn supports_interface(self: @ContractState, interface_id: u256) -> bool {
false
}
}
// fn transfer_to(ref self: ContractState, recipient: ContractAddress, token_id: u256, token_uri: u256) {
// self.hyp_erc721.transfer_to(recipient, token_id);
// }

#[generate_trait]
impl InternalImpl of InternalTrait {
fn transfer_from_sender(ref self: ContractState, token_id: u256) -> u256 {
0
}
// fn before_token_transfer(
// ref self: ContractState, from: u256, to: ContractAddress, token_id: u256, batch_size: u256
// ) {
// self.erc721.before_update(to, token_id, Zero::zero());
// }
// }

fn transfer_to(ref self: ContractState, recipient: u256, token_id: u256, token_uri: u256) {}
// would be extended when erc721_enumerable is imported
impl ERC721HooksImpl of ERC721HooksTrait<ContractState> {
fn before_update(
ref self: ERC721Component::ComponentState<ContractState>,
to: ContractAddress,
token_id: u256,
auth: ContractAddress
) {}

fn before_token_transfer(
ref self: ContractState, from: u256, to: u256, token_id: u256, batch_size: u256
fn after_update(
ref self: ERC721Component::ComponentState<ContractState>,
to: ContractAddress,
token_id: u256,
auth: ContractAddress
) {}
}

fn burn(ref self: ContractState, token_id: u256) {}

impl TokenRouterHooksImpl of TokenRouterHooksTrait<ContractState> {
fn transfer_from_sender_hook(
Realkayzee marked this conversation as resolved.
Show resolved Hide resolved
ref self: TokenRouterComponent::ComponentState<ContractState>,
amount_or_id: u256
) -> Bytes {
let contract_state = TokenRouterComponent::HasComponent::get_contract(@self);
let token_owner = contract_state.erc721.owner_of(amount_or_id);
assert!(
token_owner == get_caller_address(),
"Caller is not owner of token"
);

let mut contract_state = TokenRouterComponent::HasComponent::get_contract_mut(ref self);
contract_state.erc721.burn(amount_or_id);

BytesTrait::new_empty()
}

fn transfer_to_hook(
Realkayzee marked this conversation as resolved.
Show resolved Hide resolved
ref self: TokenRouterComponent::ComponentState<ContractState>,
recipient: u256,
amount_or_id: u256,
metadata: Bytes
) {
let recipient_felt: felt252 = recipient.try_into().expect('u256 to felt failed');
let recipient: ContractAddress = recipient_felt.try_into().unwrap();

let mut contract_state = TokenRouterComponent::HasComponent::get_contract_mut(ref self);
contract_state.erc721.mint(recipient, amount_or_id);
}
}
}
3 changes: 2 additions & 1 deletion cairo/src/contracts/token/hyp_erc721.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub mod HypErc721 {
mailbox: ContractAddress,
name: ByteArray,
symbol: ByteArray,
base_uri: ByteArray,
mint_amount: u256,
hook: ContractAddress,
interchain_security_module: ContractAddress,
Expand All @@ -136,7 +137,7 @@ pub mod HypErc721 {
self
.mailboxclient
.initialize(mailbox, Option::Some(hook), Option::Some(interchain_security_module));
self.hyp_erc721.initialize(mint_amount, name, symbol);
self.hyp_erc721.initialize(mint_amount, name, symbol, base_uri);
}

#[abi(embed_v0)]
Expand Down