1
;; Restricted wallet initialized by a third party (a variant of restricted-wallet2-code.fc)
2
;; restricts access to parts of balance until certain dates
4
() recv_internal(slice in_msg) impure {
5
;; do nothing for internal messages
8
_ seconds_passed(int start_at, int utime) inline_ref {
10
var p = config_param(-13);
11
start_at = null?(p) ? 0 : begin_parse(p).preload_uint(32);
13
return start_at ? utime - start_at : -1;
16
() recv_external(slice in_msg) impure {
17
var signature = in_msg~load_bits(512);
19
var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32));
20
throw_if(35, valid_until <= now());
21
var ds = get_data().begin_parse();
22
var (stored_seqno, stored_subwallet, public_key) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256));
23
throw_unless(33, msg_seqno == stored_seqno);
24
throw_unless(34, subwallet_id == stored_subwallet);
25
throw_unless(36, check_signature(slice_hash(in_msg), signature, public_key));
27
public_key = ds~load_uint(256); ;; load "final" public key
30
var (start_at, rdict) = (cs~load_uint(32), cs~load_dict());
34
.store_uint(stored_seqno + 1, 32)
35
.store_uint(stored_subwallet, 32)
36
.store_uint(public_key, 256)
37
.store_uint(start_at, 32)
42
var (start_at, rdict) = (ds~load_uint(32), ds~load_dict());
45
var ts = seconds_passed(start_at, now());
46
var (_, value, found) = rdict.idict_get_preveq?(32, ts);
48
raw_reserve(value~load_grams(), 2);
51
while (cs.slice_refs()) {
52
var mode = cs~load_uint(8);
53
var msg = cs~load_ref();
54
send_raw_message(msg, mode);
58
.store_uint(stored_seqno + 1, 32)
59
.store_uint(stored_subwallet, 32)
60
.store_uint(public_key, 256)
61
.store_uint(start_at, 32)
68
int seqno() method_id {
69
return get_data().begin_parse().preload_uint(32);
72
int wallet_id() method_id {
73
var ds = get_data().begin_parse();
75
return ds.preload_uint(32);
78
int get_public_key() method_id {
79
var ds = get_data().begin_parse();
80
ds~load_uint(32 + 32);
81
return ds.preload_uint(256);
84
int compute_balance_at(int utime) inline_ref {
85
var ds = get_data().begin_parse().skip_bits(32 + 32 + 256);
86
var (start_at, rdict) = (ds~load_uint(32), ds~load_dict());
88
var ts = seconds_passed(start_at, utime);
89
var balance = get_balance().pair_first();
90
var (_, value, found) = rdict.idict_get_preveq?(32, ts);
92
balance = max(balance - value~load_grams(), 0);
97
int balance_at(int utime) method_id {
98
return compute_balance_at(utime);
101
int balance() method_id {
102
return compute_balance_at(now());