diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4454552 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,72 @@ +{ + "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "array": "cpp", + "atomic": "cpp", + "hash_map": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "chrono": "cpp", + "codecvt": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cfenv": "cpp", + "cinttypes": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp" + } +} \ No newline at end of file diff --git a/wallet/inspect.fif b/wallet/inspect.fif new file mode 100644 index 0000000..eeec144 --- /dev/null +++ b/wallet/inspect.fif @@ -0,0 +1,119 @@ +"TonUtil.fif" include + +{ dup ."Inspecting order from file " type ."..." cr + file>B B>boc +} : inspect-load-boc +{ + ."usage: " @' $0 type ." " cr + ."Inspects contents of multisig .boc file." cr 1 halt +} : usage + +"inspect-this" (def?) not { + $# 1 < ' usage if + $1 =: inspect-this +} if + + +// Assuming the same external structure created by create.fif (simple external message) +// +// addr_none$00 = MsgAddressExt; +// addr_extern$01 len:(## 9) external_address:(bits len) +// = MsgAddressExt; +// anycast_info$_ depth:(#<= 30) { depth >= 1 } +// rewrite_pfx:(bits depth) = Anycast; +// addr_std$10 anycast:(Maybe Anycast) +// workchain_id:int8 address:bits256 = MsgAddressInt; +// addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) +// workchain_id:int32 address:(bits addr_len) = MsgAddressInt; +// +// ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt +// import_fee:Grams = CommonMsgInfo; +// +// +// message$_ {X:Type} info:CommonMsgInfo +// init:(Maybe (Either StateInit ^StateInit)) +// body:(Either X ^X) = Message X; +// +// +// (external message) +// +inspect-this +".boc" inspect-load-boc + { ."There seems to be an invalid header" cr } if // 1000100 => 68 + + 8 i@+ + 256 u@+ -rot + 2dup 2constant wallet_addr + ."Wallet address: " .addr cr + + Gram@+ nip // Ignore grams + + 1 u@+ swap + abort"This seems to be an init message" + + // multiSigWrapper$0 signatures:(HashmapE 4 Signature) message:(WrappedMessage X) = MultiSigWrapper X; + 1 u@+ swap + dup ."Message version: " . cr + abort"Unsupported message version!" + + dict@+ swap + dup null? abort"Empty signature list!" + + ."Signed by the following keys: " + 4 { drop . ."- " -1 } dictforeach cr drop + + // modeMessage$_ mode:uint8 body:^(Message X) = ModeMessage X; + // wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMessage X; + + 32 u@+ swap + dup ."Expires: " . + dup now < { ."(already EXPIRED!)" drop } { ."(in " now - . ."seconds)" } cond cr + + 32 u@+ swap + ."Seqno: " . cr + + 8 u@+ swap + ."Mode: " . cr + + // Now on to the actual message we're agreeing to sign + // + // int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + // src:MsgAddressInt dest:MsgAddressInt + // value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams + // created_lt:uint64 created_at:uint32 = CommonMsgInfo; + // ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt + // import_fee:Grams = CommonMsgInfo; + // ext_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt + // created_lt:uint64 created_at:uint32 = CommonMsgInfo; + cr ref@ abort"Unsupported address!" // Make things simple for now + + 8 i@+ + 256 u@+ -rot + ."Destination address: " .addr cr + + Gram@+ swap + ."Grams: " .GR cr + } cond + drop \ No newline at end of file diff --git a/wallet/merge.fif b/wallet/merge.fif new file mode 100644 index 0000000..e69de29 diff --git a/wallet/sign.fif b/wallet/sign.fif new file mode 100644 index 0000000..76241a8 --- /dev/null +++ b/wallet/sign.fif @@ -0,0 +1,50 @@ +#!/usr/bin/env -S fift -s +"TonUtil.fif" include + +{ dup ."Loading order from file " type ."..." cr + file>B B>boc +} : load-boc +{ + ."usage: " @' $0 type ." " cr + ."Signs multisig .boc file with private key loaded from file .pk and writes result to .boc" cr 1 halt +} : usage +$# 4 < ' usage if + +$1 =: input-file +$2 =: output-file +$3 =: key +$4 parse-int =: key-id + +input-file constant inspect-this +"inspect.fif" include cr + +input-file +".boc" load-boc constant order +key +".pk" load-keypair nip constant wallet_pk + + +order c constant wrapped-message + +wrapped-message ."signing message: " u@+ swap 256 B>u@ swap + + +2 boc+>B dup Bx. cr +output-file +".boc" tuck B>file +."Saved new multisigned message to file " type cr