Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* add claim_to function with starknet recipient in nostr event content

* clean claim to

* change contract address + rename

* format to felt into encode function + change signature claim_to

* scarb fmt
  • Loading branch information
MSghais authored Jun 27, 2024
1 parent b2e19e4 commit de0956e
Showing 1 changed file with 182 additions and 14 deletions.
196 changes: 182 additions & 14 deletions onchain/src/social/deposit.cairo
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
use core::fmt::Display;
use core::to_byte_array::FormatAsByteArray;
use starknet::{get_caller_address, get_contract_address, get_tx_info, ContractAddress};
use super::request::{SocialRequest, SocialRequestImpl, SocialRequestTrait, Encode, Signature};

pub type DepositId = felt252;

#[derive(Clone, Debug, Drop, Serde)]
pub struct ClaimToContent {
pub deposit_id: DepositId,
pub starknet_recipient: ContractAddress
}


impl DepositIdEncodeImpl of Encode<DepositId> {
fn encode(self: @DepositId) -> @ByteArray {
@format!("claim {}", self)
}
}

impl ClaimToContentEncodeImpl of Encode<ClaimToContent> {
fn encode(self: @ClaimToContent) -> @ByteArray {
let recipient_address_user_felt: felt252 = self
.starknet_recipient
.clone()
.try_into()
.unwrap();
@format!("claim {} to {:?}", self.deposit_id, recipient_address_user_felt)
}
}


type NostrPublicKey = u256;

#[derive(Copy, Debug, Drop, Serde)]
pub enum DepositResult {
Transfer: ContractAddress,
Deposit: DepositId,
Deposit: DepositId
}

#[derive(Copy, Debug, Drop, PartialEq, starknet::Store, Serde)]
Expand All @@ -38,6 +59,7 @@ pub trait IDepositEscrow<TContractState> {
) -> DepositResult;
fn cancel(ref self: TContractState, deposit_id: DepositId);
fn claim(ref self: TContractState, request: SocialRequest<DepositId>);
fn claim_to(ref self: TContractState, request: SocialRequest<ClaimToContent>);
}

#[starknet::contract]
Expand All @@ -55,6 +77,7 @@ pub mod DepositEscrow {

use super::{
Deposit, DepositId, DepositResult, IDepositEscrow, NostrPublicKey, DepositIdEncodeImpl,
ClaimToContent
};

impl DepositDefault of Default<Deposit> {
Expand Down Expand Up @@ -252,6 +275,38 @@ pub mod DepositEscrow {
}
);
}


fn claim_to(ref self: ContractState, request: SocialRequest<ClaimToContent>) {
let deposit_content = request.content.clone();
let deposit_id = deposit_content.deposit_id;
// let starknet_recipient: ContractAddress = deposit_content.starknet_recipient;
let starknet_recipient: ContractAddress = deposit_content
.starknet_recipient
.try_into()
.unwrap();
let deposit = self.deposits.read(deposit_id);
assert!(deposit != Default::default(), "can't find deposit");
assert!(request.public_key == deposit.recipient, "invalid recipient");
request.verify().expect('can\'t verify signature');

let erc20 = IERC20Dispatcher { contract_address: deposit.token_address };
erc20.transfer(starknet_recipient, deposit.amount);

self.nostr_to_sn.write(request.public_key, starknet_recipient);
self.deposits.write(deposit_id, Default::default());
self
.emit(
ClaimEvent {
deposit_id,
sender: get_caller_address(),
nostr_recipient: request.public_key,
amount: deposit.amount,
starknet_recipient: starknet_recipient,
token_address: deposit.token_address
}
);
}
}
}

Expand All @@ -264,16 +319,17 @@ mod tests {
use snforge_std::{
declare, ContractClass, ContractClassTrait, spy_events, SpyOn, EventSpy, EventFetcher,
Event, EventAssertions, start_cheat_caller_address, cheat_caller_address_global,
stop_cheat_caller_address_global, start_cheat_block_timestamp
stop_cheat_caller_address_global, start_cheat_block_timestamp,
};
use starknet::{
ContractAddress, get_block_timestamp, get_caller_address, get_contract_address,
contract_address_const
contract_address_const,
// contract_address_try_from_felt252
};

use super::super::request::{SocialRequest, Signature, Encode};
use super::super::transfer::Transfer;
use super::{Deposit, DepositId, DepositResult, IDepositEscrow, NostrPublicKey};
use super::{Deposit, DepositId, DepositResult, IDepositEscrow, NostrPublicKey, ClaimToContent};
use super::{IDepositEscrowDispatcher, IDepositEscrowDispatcherTrait};

fn declare_escrow() -> ContractClass {
Expand Down Expand Up @@ -319,7 +375,8 @@ mod tests {
NostrPublicKey,
ContractAddress,
IERC20Dispatcher,
IDepositEscrowDispatcher
IDepositEscrowDispatcher,
SocialRequest<ClaimToContent>
) {
// recipient private key: 59a772c0e643e4e2be5b8bac31b2ab5c5582b03a84444c81d6e2eec34a5e6c35
// just for testing, do not use for anything else
Expand All @@ -332,6 +389,11 @@ mod tests {

let escrow = deploy_escrow(escrow_class);

let recipient_address_user: ContractAddress = 678.try_into().unwrap();

let recipient_address_user_felt: felt252 = recipient_address_user.try_into().unwrap();

// TODO how format it to use this starknet address on the test data Nostr event
// for test data see: https://replit.com/@maciejka/WanIndolentKilobyte-2

let request = SocialRequest {
Expand All @@ -346,15 +408,38 @@ mod tests {
}
};

(request, recipient_public_key, sender_address, erc20, escrow)
// TODO change with the correct signature with the content deposit id and strk recipient
// for test data see claim to: https://replit.com/@msghais135/WanIndolentKilobyte-claimto#index.js

let claim_content = ClaimToContent {
deposit_id: 1, starknet_recipient: recipient_address_user
};

// @TODO format the content and get the correct signature
let request_claim_to = SocialRequest {
public_key: recipient_public_key,
created_at: 1716285235_u64,
kind: 1_u16,
tags: "[]",
content: claim_content,
sig: Signature {
r: 0x3d9628eeb7ff7333bdea8e48e2371279363a4aac5c8da19144e909d9744ebc82_u256,
s: 0xe9f41be1e8f1719ab1da3b69c74cad3045fcc06b0020d989eb8b42f1e88574da_u256
// r: 0xf61fa9ab434b047a13a6b679fa8b2152ed20f6859bf566987b2e6430dae8a0c2_u256,
// s: 0xafdfd907640f7d17805541429e7da3633ae4a39d9ad091edf283e9500a689c81_u256,
}
};

(request, recipient_public_key, sender_address, erc20, escrow, request_claim_to)
}

fn request_fixture() -> (
SocialRequest<DepositId>,
NostrPublicKey,
ContractAddress,
IERC20Dispatcher,
IDepositEscrowDispatcher
IDepositEscrowDispatcher,
SocialRequest<ClaimToContent>
) {
let erc20_class = declare_erc20();
let escrow_class = declare_escrow();
Expand All @@ -363,7 +448,7 @@ mod tests {

#[test]
fn deposit_claim() {
let (request, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (request, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();
let recipient_address: ContractAddress = 345.try_into().unwrap();
let amount = 100_u256;

Expand All @@ -378,10 +463,30 @@ mod tests {
escrow.claim(request);
}

#[test]
fn deposit_claim_to() {
let (request, recipient_nostr_key, sender_address, erc20, escrow, request_claim_to) =
request_fixture();
let recipient_address: ContractAddress = 345.try_into().unwrap();
let recipient_address_user: ContractAddress = 678.try_into().unwrap();
let amount = 100_u256;

cheat_caller_address_global(sender_address);
erc20.approve(escrow.contract_address, amount);
stop_cheat_caller_address_global();

start_cheat_caller_address(escrow.contract_address, sender_address);
escrow.deposit(amount, erc20.contract_address, recipient_nostr_key, 0_u64);

start_cheat_caller_address(escrow.contract_address, recipient_address);
// escrow.claim_to(request_claim_to, recipient_address_user);
escrow.claim_to(request_claim_to);
}

#[test]
#[should_panic(expected: 'can\'t verify signature')]
fn claim_incorrect_signature() {
let (request, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (request, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();
let recipient_address: ContractAddress = 345.try_into().unwrap();
let amount = 100_u256;

Expand All @@ -405,9 +510,72 @@ mod tests {
escrow.claim(request);
}

#[test]
#[should_panic(expected: 'can\'t verify signature')]
fn claim_incorrect_signature_claim_to() {
let (request, recipient_nostr_key, sender_address, erc20, escrow, request_claim_to) =
request_fixture();
let recipient_address: ContractAddress = 345.try_into().unwrap();
let recipient_address_user: ContractAddress = 678.try_into().unwrap();

let amount = 100_u256;

cheat_caller_address_global(sender_address);
erc20.approve(escrow.contract_address, amount);
stop_cheat_caller_address_global();

start_cheat_caller_address(escrow.contract_address, sender_address);
escrow.deposit(amount, erc20.contract_address, recipient_nostr_key, 0_u64);

start_cheat_caller_address(escrow.contract_address, recipient_address);

let request = SocialRequest {
sig: Signature {
r: 0x2570a9a0c92c180bd4ac826c887e63844b043e3b65da71a857d2aa29e7cd3a4e_u256,
s: 0x1c0c0a8b7a8330b6b8915985c9cd498a407587213c2e7608e7479b4ef966605f_u256,
},
..request_claim_to,
};

// escrow.claim_to(request, recipient_address_user);
escrow.claim_to(request);
}


#[test]
#[should_panic(expected: 'can\'t verify signature')]
fn claim_incorrect_signature_claim_to_incorrect_recipient() {
let (request, recipient_nostr_key, sender_address, erc20, escrow, request_claim_to) =
request_fixture();
let recipient_address: ContractAddress = 345.try_into().unwrap();
let recipient_address_user: ContractAddress = 789.try_into().unwrap();

let amount = 100_u256;

cheat_caller_address_global(sender_address);
erc20.approve(escrow.contract_address, amount);
stop_cheat_caller_address_global();

start_cheat_caller_address(escrow.contract_address, sender_address);
escrow.deposit(amount, erc20.contract_address, recipient_nostr_key, 0_u64);

start_cheat_caller_address(escrow.contract_address, recipient_address);

let request = SocialRequest {
sig: Signature {
r: 0x2570a9a0c92c180bd4ac826c887e63844b043e3b65da71a857d2aa29e7cd3a4e_u256,
s: 0x1c0c0a8b7a8330b6b8915985c9cd498a407587213c2e7608e7479b4ef966605f_u256,
},
..request_claim_to,
};

// escrow.claim_to(request, recipient_address_user);
escrow.claim_to(request);
}

#[test]
fn deposit_cancel_no_timelock() {
let (_, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (_, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();

let amount = 100_u256;

Expand All @@ -429,7 +597,7 @@ mod tests {
#[test]
#[should_panic(expected: "can't cancel before timelock expiration")]
fn deposit_cancel_before_timelock() {
let (_, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (_, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();

let amount = 100_u256;

Expand All @@ -448,7 +616,7 @@ mod tests {

#[test]
fn deposit_cancel_timelock() {
let (_, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (_, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();

let amount = 100_u256;

Expand All @@ -471,7 +639,7 @@ mod tests {
#[test]
#[should_panic(expected: "not authorized")]
fn not_authorized_cancel() {
let (_, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (_, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();

let amount = 100_u256;

Expand All @@ -490,7 +658,7 @@ mod tests {
}

fn deposit_claim_deposit() {
let (request, recipient_nostr_key, sender_address, erc20, escrow) = request_fixture();
let (request, recipient_nostr_key, sender_address, erc20, escrow, _) = request_fixture();
let recipient_address: ContractAddress = 345.try_into().unwrap();
let amount = 100_u256;

Expand Down

0 comments on commit de0956e

Please sign in to comment.