Skip to content

Commit bbd824f

Browse files
authored
Merge pull request #20 from enigmampc/send-without-register
SNIP23: Add an optional recipient_code_hash to send operations
2 parents 9e51ac4 + e8d569d commit bbd824f

File tree

5 files changed

+106
-28
lines changed

5 files changed

+106
-28
lines changed

src/batch.rs

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub struct TransferAction {
1717
#[serde(rename_all = "snake_case")]
1818
pub struct SendAction {
1919
pub recipient: HumanAddr,
20+
pub recipient_code_hash: Option<String>,
2021
pub amount: Uint128,
2122
pub msg: Option<Binary>,
2223
pub memo: Option<String>,
@@ -36,6 +37,7 @@ pub struct TransferFromAction {
3637
pub struct SendFromAction {
3738
pub owner: HumanAddr,
3839
pub recipient: HumanAddr,
40+
pub recipient_code_hash: Option<String>,
3941
pub amount: Uint128,
4042
pub msg: Option<Binary>,
4143
pub memo: Option<String>,

src/contract.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,12 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
152152
} => try_transfer(deps, env, recipient, amount, memo),
153153
HandleMsg::Send {
154154
recipient,
155+
recipient_code_hash,
155156
amount,
156157
msg,
157158
memo,
158159
..
159-
} => try_send(deps, env, recipient, amount, memo, msg),
160+
} => try_send(deps, env, recipient, recipient_code_hash, amount, memo, msg),
160161
HandleMsg::BatchTransfer { actions, .. } => try_batch_transfer(deps, env, actions),
161162
HandleMsg::BatchSend { actions, .. } => try_batch_send(deps, env, actions),
162163
HandleMsg::Burn { amount, memo, .. } => try_burn(deps, env, amount, memo),
@@ -187,11 +188,21 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
187188
HandleMsg::SendFrom {
188189
owner,
189190
recipient,
191+
recipient_code_hash,
190192
amount,
191193
msg,
192194
memo,
193195
..
194-
} => try_send_from(deps, env, owner, recipient, amount, memo, msg),
196+
} => try_send_from(
197+
deps,
198+
env,
199+
owner,
200+
recipient,
201+
recipient_code_hash,
202+
amount,
203+
memo,
204+
msg,
205+
),
195206
HandleMsg::BatchTransferFrom { actions, .. } => {
196207
try_batch_transfer_from(deps, &env, actions)
197208
}
@@ -847,12 +858,21 @@ fn try_add_receiver_api_callback<S: ReadonlyStorage>(
847858
storage: &S,
848859
messages: &mut Vec<CosmosMsg>,
849860
recipient: HumanAddr,
861+
recipient_code_hash: Option<String>,
850862
msg: Option<Binary>,
851863
sender: HumanAddr,
852864
from: HumanAddr,
853865
amount: Uint128,
854866
memo: Option<String>,
855867
) -> StdResult<()> {
868+
if let Some(receiver_hash) = recipient_code_hash {
869+
let receiver_msg = Snip20ReceiveMsg::new(sender, from, amount, memo, msg);
870+
let callback_msg = receiver_msg.into_cosmos_msg(receiver_hash, recipient)?;
871+
872+
messages.push(callback_msg);
873+
return Ok(());
874+
}
875+
856876
let receiver_hash = get_receiver_hash(storage, &recipient);
857877
if let Some(receiver_hash) = receiver_hash {
858878
let receiver_hash = receiver_hash?;
@@ -871,6 +891,7 @@ fn try_send_impl<S: Storage, A: Api, Q: Querier>(
871891
sender: HumanAddr,
872892
sender_canon: &CanonicalAddr, // redundant but more efficient
873893
recipient: HumanAddr,
894+
recipient_code_hash: Option<String>,
874895
amount: Uint128,
875896
memo: Option<String>,
876897
msg: Option<Binary>,
@@ -890,6 +911,7 @@ fn try_send_impl<S: Storage, A: Api, Q: Querier>(
890911
&deps.storage,
891912
messages,
892913
recipient,
914+
recipient_code_hash,
893915
msg,
894916
sender.clone(),
895917
sender,
@@ -904,6 +926,7 @@ fn try_send<S: Storage, A: Api, Q: Querier>(
904926
deps: &mut Extern<S, A, Q>,
905927
env: Env,
906928
recipient: HumanAddr,
929+
recipient_code_hash: Option<String>,
907930
amount: Uint128,
908931
memo: Option<String>,
909932
msg: Option<Binary>,
@@ -917,6 +940,7 @@ fn try_send<S: Storage, A: Api, Q: Querier>(
917940
sender,
918941
&sender_canon,
919942
recipient,
943+
recipient_code_hash,
920944
amount,
921945
memo,
922946
msg,
@@ -946,6 +970,7 @@ fn try_batch_send<S: Storage, A: Api, Q: Querier>(
946970
sender.clone(),
947971
&sender_canon,
948972
action.recipient,
973+
action.recipient_code_hash,
949974
action.amount,
950975
action.memo,
951976
action.msg,
@@ -1097,6 +1122,7 @@ fn try_send_from_impl<S: Storage, A: Api, Q: Querier>(
10971122
spender_canon: &CanonicalAddr, // redundant but more efficient
10981123
owner: HumanAddr,
10991124
recipient: HumanAddr,
1125+
recipient_code_hash: Option<String>,
11001126
amount: Uint128,
11011127
memo: Option<String>,
11021128
msg: Option<Binary>,
@@ -1117,6 +1143,7 @@ fn try_send_from_impl<S: Storage, A: Api, Q: Querier>(
11171143
&deps.storage,
11181144
messages,
11191145
recipient,
1146+
recipient_code_hash,
11201147
msg,
11211148
env.message.sender,
11221149
owner,
@@ -1132,6 +1159,7 @@ fn try_send_from<S: Storage, A: Api, Q: Querier>(
11321159
env: Env,
11331160
owner: HumanAddr,
11341161
recipient: HumanAddr,
1162+
recipient_code_hash: Option<String>,
11351163
amount: Uint128,
11361164
memo: Option<String>,
11371165
msg: Option<Binary>,
@@ -1147,6 +1175,7 @@ fn try_send_from<S: Storage, A: Api, Q: Querier>(
11471175
&spender_canon,
11481176
owner,
11491177
recipient,
1178+
recipient_code_hash,
11501179
amount,
11511180
memo,
11521181
msg,
@@ -1177,6 +1206,7 @@ fn try_batch_send_from<S: Storage, A: Api, Q: Querier>(
11771206
&spender_canon,
11781207
action.owner,
11791208
action.recipient,
1209+
action.recipient_code_hash,
11801210
action.amount,
11811211
action.memo,
11821212
action.msg,
@@ -1926,6 +1956,7 @@ mod tests {
19261956

19271957
let handle_msg = HandleMsg::Send {
19281958
recipient: HumanAddr("contract".to_string()),
1959+
recipient_code_hash: None,
19291960
amount: Uint128(100),
19301961
memo: Some("my memo".to_string()),
19311962
padding: None,
@@ -2200,6 +2231,7 @@ mod tests {
22002231
let handle_msg = HandleMsg::SendFrom {
22012232
owner: HumanAddr("bob".to_string()),
22022233
recipient: HumanAddr("alice".to_string()),
2234+
recipient_code_hash: None,
22032235
amount: Uint128(2500),
22042236
memo: None,
22052237
msg: None,
@@ -2225,6 +2257,7 @@ mod tests {
22252257
let handle_msg = HandleMsg::SendFrom {
22262258
owner: HumanAddr("bob".to_string()),
22272259
recipient: HumanAddr("alice".to_string()),
2260+
recipient_code_hash: None,
22282261
amount: Uint128(2500),
22292262
memo: None,
22302263
msg: None,
@@ -2256,6 +2289,7 @@ mod tests {
22562289
let handle_msg = HandleMsg::SendFrom {
22572290
owner: HumanAddr("bob".to_string()),
22582291
recipient: HumanAddr("contract".to_string()),
2292+
recipient_code_hash: None,
22592293
amount: Uint128(2000),
22602294
memo: Some("my memo".to_string()),
22612295
msg: Some(send_msg),
@@ -2293,6 +2327,7 @@ mod tests {
22932327
let handle_msg = HandleMsg::SendFrom {
22942328
owner: HumanAddr("bob".to_string()),
22952329
recipient: HumanAddr("alice".to_string()),
2330+
recipient_code_hash: None,
22962331
amount: Uint128(1),
22972332
memo: None,
22982333
msg: None,

src/msg.rs

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub enum HandleMsg {
9999
},
100100
Send {
101101
recipient: HumanAddr,
102+
recipient_code_hash: Option<String>,
102103
amount: Uint128,
103104
msg: Option<Binary>,
104105
memo: Option<String>,
@@ -153,6 +154,7 @@ pub enum HandleMsg {
153154
SendFrom {
154155
owner: HumanAddr,
155156
recipient: HumanAddr,
157+
recipient_code_hash: Option<String>,
156158
amount: Uint128,
157159
msg: Option<Binary>,
158160
memo: Option<String>,

tests/example-receiver/src/contract.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -126,33 +126,33 @@ pub fn try_receive<S: Storage, A: Api, Q: Querier>(
126126
));
127127
}
128128

129-
let state = config_read(&deps.storage).load()?;
130-
if !state.known_snip_20.contains(&env.message.sender) {
131-
return Err(StdError::generic_err(format!(
132-
"{} is not a known SNIP-20 coin that this contract registered to",
133-
env.message.sender
134-
)));
135-
}
129+
// let state = config_read(&deps.storage).load()?;
130+
// if !state.known_snip_20.contains(&env.message.sender) {
131+
// return Err(StdError::generic_err(format!(
132+
// "{} is not a known SNIP-20 coin that this contract registered to",
133+
// env.message.sender
134+
// )));
135+
// }
136136

137137
/* use sender & amount */
138138
handle(deps, env, msg)
139139
}
140140

141141
fn try_redeem<S: Storage, A: Api, Q: Querier>(
142-
deps: &mut Extern<S, A, Q>,
142+
_deps: &Extern<S, A, Q>,
143143
env: Env,
144144
addr: HumanAddr,
145145
hash: String,
146146
to: HumanAddr,
147147
amount: Uint128,
148148
) -> StdResult<HandleResponse> {
149-
let state = config_read(&deps.storage).load()?;
150-
if !state.known_snip_20.contains(&addr) {
151-
return Err(StdError::generic_err(format!(
152-
"{} is not a known SNIP-20 coin that this contract registered to",
153-
addr
154-
)));
155-
}
149+
// let state = config_read(&deps.storage).load()?;
150+
// if !state.known_snip_20.contains(&addr) {
151+
// return Err(StdError::generic_err(format!(
152+
// "{} is not a known SNIP-20 coin that this contract registered to",
153+
// addr
154+
// )));
155+
// }
156156

157157
let msg = to_binary(&Snip20Msg::redeem(amount))?;
158158
let secret_redeem = CosmosMsg::Wasm(WasmMsg::Execute {

tests/integration.sh

+50-11
Original file line numberDiff line numberDiff line change
@@ -949,13 +949,18 @@ function register_receiver() {
949949
function test_send() {
950950
set -e
951951
local contract_addr="$1"
952+
local skip_register_receiver="$2"
952953

953954
log_test_header
954955

955956
local receiver_addr
956957
receiver_addr="$(create_receiver_contract)"
957-
# receiver_addr='secret17k8qt6aqd7eee3fawmtvy4vu6teqx8d7mdm49x'
958-
register_receiver "$receiver_addr" "$contract_addr"
958+
local receiver_hash
959+
receiver_hash="$(secretcli q compute contract-hash $receiver_addr | sed 's/^0x//')"
960+
961+
if [ "$skip_register_receiver" != "skip-register" ]; then
962+
register_receiver "$receiver_addr" "$contract_addr"
963+
fi
959964

960965
local tx_hash
961966

@@ -968,7 +973,8 @@ function test_send() {
968973

969974
# Try to send more than "a" has
970975
log 'sending funds from "a" to "b", but more than "a" has'
971-
local send_message='{"send":{"recipient":"'"${ADDRESS[b]}"'","amount":"1000001"}}'
976+
local send_message
977+
send_message='{"send":{"recipient":"'"${ADDRESS[b]}"'","amount":"1000001"}}'
972978
local send_response
973979
tx_hash="$(compute_execute "$contract_addr" "$send_message" ${FROM[a]} --gas 150000)"
974980
# Notice the `!` before the command - it is EXPECTED to fail.
@@ -998,8 +1004,15 @@ function test_send() {
9981004
log 'sending funds from "a" to the Receiver, with message to the Receiver'
9991005
local receiver_msg='{"increment":{}}'
10001006
receiver_msg="$(base64 <<<"$receiver_msg")"
1001-
local send_message='{"send":{"recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1007+
1008+
if [ "$skip_register_receiver" = "skip-register" ]; then
1009+
send_message='{"send":{"recipient":"'"$receiver_addr"'","recipient_code_hash":"'"$receiver_hash"'","amount":"400000","msg":"'$receiver_msg'"}}'
1010+
else
1011+
send_message='{"send":{"recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1012+
fi
1013+
10021014
local send_response
1015+
10031016
tx_hash="$(compute_execute "$contract_addr" "$send_message" ${FROM[a]} --gas 300000)"
10041017
send_response="$(wait_for_compute_tx "$tx_hash" 'waiting for send from "a" to the Receiver to process')"
10051018
assert_eq \
@@ -1040,7 +1053,13 @@ function test_send() {
10401053
log 'sending funds from "a" to the Receiver, with a "Fail" message to the Receiver'
10411054
receiver_msg='{"fail":{}}'
10421055
receiver_msg="$(base64 <<<"$receiver_msg")"
1043-
send_message='{"send":{"recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1056+
1057+
if [ "$skip_register_receiver" = "skip-register" ]; then
1058+
send_message='{"send":{"recipient":"'"$receiver_addr"'","recipient_code_hash":"'"$receiver_hash"'","amount":"400000","msg":"'$receiver_msg'"}}'
1059+
else
1060+
send_message='{"send":{"recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1061+
fi
1062+
10441063
tx_hash="$(compute_execute "$contract_addr" "$send_message" ${FROM[a]} --gas 300000)"
10451064
# Notice the `!` before the command - it is EXPECTED to fail.
10461065
! send_response="$(wait_for_compute_tx "$tx_hash" 'waiting for send from "a" to the Receiver to process')"
@@ -1265,13 +1284,18 @@ function test_transfer_from() {
12651284
function test_send_from() {
12661285
set -e
12671286
local contract_addr="$1"
1287+
local skip_register_receiver="$2"
12681288

12691289
log_test_header
12701290

12711291
local receiver_addr
12721292
receiver_addr="$(create_receiver_contract)"
1273-
# receiver_addr='secret17k8qt6aqd7eee3fawmtvy4vu6teqx8d7mdm49x'
1274-
register_receiver "$receiver_addr" "$contract_addr"
1293+
local receiver_hash
1294+
receiver_hash="$(secretcli q compute contract-hash $receiver_addr | sed 's/^0x//')"
1295+
1296+
if [ "$skip_register_receiver" != "skip-register" ]; then
1297+
register_receiver "$receiver_addr" "$contract_addr"
1298+
fi
12751299

12761300
local tx_hash
12771301

@@ -1322,7 +1346,14 @@ function test_send_from() {
13221346
log 'sending funds from "a", using "b", to the Receiver, with message to the Receiver'
13231347
local receiver_msg='{"increment":{}}'
13241348
receiver_msg="$(base64 <<<"$receiver_msg")"
1325-
local send_message='{"send_from":{"owner":"'"${ADDRESS[a]}"'","recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1349+
1350+
local send_message
1351+
if [ "$skip_register_receiver" = "skip-register" ]; then
1352+
send_message='{"send_from":{"owner":"'"${ADDRESS[a]}"'","recipient":"'"$receiver_addr"'","recipient_code_hash":"'"$receiver_hash"'","amount":"400000","msg":"'$receiver_msg'"}}'
1353+
else
1354+
send_message='{"send_from":{"owner":"'"${ADDRESS[a]}"'","recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1355+
fi
1356+
13261357
local send_response
13271358
tx_hash="$(compute_execute "$contract_addr" "$send_message" ${FROM[b]} --gas 302000)"
13281359
send_response="$(wait_for_compute_tx "$tx_hash" 'waiting for send from "a" to the Receiver to process')"
@@ -1377,7 +1408,13 @@ function test_send_from() {
13771408
log 'sending funds from "a", using "b", to the Receiver, with a "Fail" message to the Receiver'
13781409
receiver_msg='{"fail":{}}'
13791410
receiver_msg="$(base64 <<<"$receiver_msg")"
1380-
send_message='{"send_from":{"owner":"'"${ADDRESS[a]}"'", "recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1411+
1412+
if [ "$skip_register_receiver" = "skip-register" ]; then
1413+
send_message='{"send_from":{"owner":"'"${ADDRESS[a]}"'","recipient":"'"$receiver_addr"'","recipient_code_hash":"'"$receiver_hash"'","amount":"400000","msg":"'$receiver_msg'"}}'
1414+
else
1415+
send_message='{"send_from":{"owner":"'"${ADDRESS[a]}"'","recipient":"'"$receiver_addr"'","amount":"400000","msg":"'$receiver_msg'"}}'
1416+
fi
1417+
13811418
tx_hash="$(compute_execute "$contract_addr" "$send_message" ${FROM[b]} --gas 300000)"
13821419
# Notice the `!` before the command - it is EXPECTED to fail.
13831420
! send_response="$(wait_for_compute_tx "$tx_hash" 'waiting for send from "a" to the Receiver to process')"
@@ -1420,10 +1457,12 @@ function main() {
14201457
test_viewing_key "$contract_addr"
14211458
test_deposit "$contract_addr"
14221459
test_transfer "$contract_addr"
1423-
test_send "$contract_addr"
1460+
test_send "$contract_addr" register
1461+
test_send "$contract_addr" skip-register
14241462
test_burn "$contract_addr"
14251463
test_transfer_from "$contract_addr"
1426-
test_send_from "$contract_addr"
1464+
test_send_from "$contract_addr" register
1465+
test_send_from "$contract_addr" skip-register
14271466

14281467
log 'Tests completed successfully'
14291468

0 commit comments

Comments
 (0)