diff --git a/container/src/hledger-flow/accounts/electrum/electrum-shared.bash b/container/src/hledger-flow/accounts/electrum/electrum-shared.bash index 48e8453..9132bea 100755 --- a/container/src/hledger-flow/accounts/electrum/electrum-shared.bash +++ b/container/src/hledger-flow/accounts/electrum/electrum-shared.bash @@ -34,7 +34,8 @@ source "${DOCKER_FINANCE_CONTAINER_REPO}/src/hledger-flow/lib/lib_preprocess.bas [ -z "$global_in_path" ] && exit 1 [ -z "$global_out_path" ] && exit 1 -function parse() +# Since electrum 3.3.0 +function parse_without-lightning-header() { lib_preprocess::assert_header "transaction_hash,label,confirmations,value,fiat_value,fee,fiat_fee,timestamp" @@ -43,19 +44,49 @@ function parse() if (NR<2 || $8 !~ global_year) next - printf $1 OFS # transaction_hash + # + # transaction_hash (oc_transaction_hash) + # + + printf $1 OFS + + # + # ln_payment_hash (N/A) + # + + printf OFS + + # + # label + # sub(/%/, "%%", $2) - printf $2 OFS # label + printf $2 OFS - printf $3 OFS # confirmations + # + # confirmations + # - # value (without fee) - direction=($4 ~ /^-/ ? "OUT" : "IN"); sub(/^-/, "", $4) - value=$4-$6 # Remove fee + printf $3 OFS + + # + # value (amount_chain_bc) + # + + direction = ($4 ~ /^-/ ? "OUT" : "IN"); sub(/^-/, "", $4) + value = $4 - $6 # Remove included network fee printf("%.8f", value); printf OFS + # + # amount_lightning_bc (N/A) + # + + printf OFS + + # # fiat_value + # + if ($5 !~ /^No Data$/) { sub(/^-/, "", $5) @@ -63,22 +94,161 @@ function parse() } printf OFS - # fee + # + # fee (network_fee_satoshi) + # + printf("%.8f", $6) printf OFS + # # fiat_fee + # + if ($7 !~ /^No Data$/) { printf("%.8f", $7) } printf OFS + # # timestamp + # + sub(/ /, "T", $8) # HACK: makes arg-friendly by removing space cmd = "date \"+%F %T %z\" --date="$8 | getline date printf date OFS + # + # Direction, subaccount + # + + printf direction OFS + printf global_subaccount + + printf "\n" + + }' FS=, OFS=, "$global_in_path" >"$global_out_path" +} + +# Since electrum 4.6.2 +# TODO: *WARNING*: lightning support is a WIP due to an unresolved electrum lightning history bug (see docker-finance #227) +function parse_with-lightning-header() +{ + lib_preprocess::assert_header "oc_transaction_hash,ln_payment_hash,label,confirmations,amount_chain_bc,amount_lightning_bc,fiat_value,network_fee_satoshi,fiat_fee,timestamp" + + gawk -v global_year="$global_year" -v global_subaccount="$global_subaccount" \ + '{ + if (NR<2 || $10 !~ global_year) + next + + # + # oc_transaction_hash + # + + printf $1 OFS + + # + # ln_payment_hash + # + + printf $2 OFS + + # + # label + # + + sub(/%/, "%%", $3) + printf $3 OFS + + # + # confirmations + # + + printf $4 OFS + + # + # amount_chain_bc + # + + direction = ($5 ~ /^-/ ? "OUT" : "IN"); sub(/^-/, "", $5) + + # Network fee is now in satoshis + network_fee = $8 * 0.00000001 + + # Remove included network fee + oc_amount = ($5 > 0 ? $5 - network_fee : $5) + + printf("%.8f", oc_amount); printf OFS + + # + # amount_lightning_bc + # + + # NOTE: opening a channel will be positive but it is not an IN + if (direction == "IN") + { + if ($6 ~ /^-/) + { + direction = "OUT" + } + else + { + direction = "IN" + } + } + sub(/^-/, "", $6) + + # If lightning hash exists, is not opening/closing a channel + if ($2 ~ /[a-z0-9]/) + { + ln_amount = ($6 > 0 ? $6 - network_fee : $6) + } + else + { + ln_amount = $6 + } + printf("%.8f", ln_amount); printf OFS + + # + # fiat_value + # + + if ($7 !~ /^No Data$|^$/) + { + sub(/^-/, "", $7) + printf("%.8f", $7) + } + printf OFS + + # + # network_fee_satoshi + # + + printf("%.8f", network_fee); printf OFS + + # + # fiat_fee + # + + if ($9 !~ /^No Data$|^$/) + { + printf("%.8f", $9) + } + printf OFS + + # + # timestamp + # + + sub(/ /, "T", $10) # HACK: makes arg-friendly by removing space + cmd = "date \"+%F %T %z\" --date="$10 | getline date + printf date OFS + + # + # Direction, subaccount + # + printf direction OFS printf global_subaccount @@ -89,7 +259,11 @@ function parse() function main() { - parse + lib_preprocess::test_header "transaction_hash,label,confirmations,value,fiat_value,fee,fiat_fee,timestamp" \ + && parse_without-lightning-header && return 0 + + lib_preprocess::test_header "oc_transaction_hash,ln_payment_hash,label,confirmations,amount_chain_bc,amount_lightning_bc,fiat_value,network_fee_satoshi,fiat_fee,timestamp" \ + && parse_with-lightning-header } main "$@" diff --git a/container/src/hledger-flow/accounts/electrum/electrum-shared.rules b/container/src/hledger-flow/accounts/electrum/electrum-shared.rules index 34cc51c..398adb3 100644 --- a/container/src/hledger-flow/accounts/electrum/electrum-shared.rules +++ b/container/src/hledger-flow/accounts/electrum/electrum-shared.rules @@ -15,74 +15,191 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -fields txid,label,confirmations,value_without_fee,fiat_value,fee,fiat_fee,timestamp,direction,subaccount +# TODO: *WARNING*: lightning support is a WIP due to an unresolved electrum lightning history bug (see docker-finance #227) + +fields oc_hash,ln_hash,label,confirmations,oc_amount,ln_amount,fiat_value,network_fee,fiat_fee,timestamp,direction,subaccount # Electrum exports to localtime date-format %Y-%m-%d %H:%M:%S %z date %timestamp +# Actual description must be kept as a notes tag description %timestamp -# Treat the Electrum 'label' field as notes -comment txid:%txid, notes:%label, direction:%direction - account1 assets:electrum:%subaccount:BTC -amount %value_without_fee BTC +amount %oc_amount BTC -if %direction ^OUT$ - amount -%value_without_fee BTC +comment txid:%oc_hash, notes:%label, direction:%direction + +if %ln_hash [0-9a-z] + comment txid:%oc_hash, ln_hash:%ln_hash, notes:%label, direction:%direction # -# Set account based 'label' keywords -# - # IN +# if %direction ^IN$ account2 equity:electrum:%subaccount:withdrawal:BTC +if %direction ^IN$ +& %oc_amount [1-9] +& %ln_amount [1-9] + amount2 -%oc_amount BTC + account3 assets:electrum:%subaccount:ln_locked_payable:BTC + amount3 %ln_amount BTC + account3 assets:electrum:%subaccount:BTC + amount4 -%ln_amount BTC + +if %direction ^IN$ +& %oc_amount ^[^1-9]*$ +& %ln_amount [1-9] + amount %ln_amount BTC + amount2 -%ln_amount BTC + +# Label: lightning channels + +if %direction ^IN$ +& %oc_amount [1-9] +& %ln_amount [1-9] +& %label ^Close channel + amount %ln_amount BTC + account2 assets:electrum:%subaccount:ln_locked_payable:BTC + +# Labels: income + if %direction ^IN$ & %label (Income|Payment) account2 income:electrum:%subaccount:BTC - comment txid:%txid, notes:%label, direction:%direction, taxed_as:INCOME - comment2 %timestamp,INCOME,electrum:%subaccount:BTC,BTC,%value_without_fee,USD,%fiat_value,%label + comment txid:%oc_hash, notes:%label, direction:%direction, taxed_as:INCOME + comment2 %timestamp,INCOME,electrum:%subaccount:BTC,BTC,%oc_amount,USD,%fiat_value,%label + +if %direction ^IN$ +& %label (Income|Payment) +& %ln_amount [1-9] + comment ln_hash:%ln_hash, notes:%label, direction:%direction, taxed_as:INCOME + comment2 %timestamp,INCOME,electrum:%subaccount:BTC,BTC,%ln_amount,USD,%fiat_value,%label + +# Labels: gifts +# NOTE: fiat_value must be manually updated in custom rules if cost-basis will be different than given fiat_value + +# TODO: add regex for donate/donation +# TODO: separate donations from gifts subaccount +if %direction ^IN$ +& %label Gift +& %oc_amount [1-9] + account2 income:electrum:%subaccount:gifts:BTC + comment txid:%oc_hash, notes:%label, direction:%direction, taxed_as:GIFTIN + comment2 %timestamp,GIFTIN,electrum:%subaccount:BTC,BTC,%oc_amount,USD,%fiat_value,%label if %direction ^IN$ & %label Gift - account2 income:electrum:%subaccount:gifts:BTC - comment txid:%txid, notes:%label, direction:%direction, taxed_as:GIFTIN - comment2 %timestamp,GIFTIN,electrum:%subaccount:BTC,BTC,%value_without_fee,USD,%fiat_value,%label -# NOTE: fiat_value must be manually updated in custom rules if your given cost-basis will be different +& %ln_amount [1-9] + comment ln_hash:%ln_hash, notes:%label, direction:%direction, taxed_as:GIFTIN + comment2 %timestamp,GIFTIN,electrum:%subaccount:BTC,BTC,%ln_amount,USD,%fiat_value,%label +# # OUT +# if %direction ^OUT$ + amount -%oc_amount BTC account2 expenses:electrum:%subaccount:BTC - comment txid:%txid, notes:%label, taxed_as:SPEND - comment2 %timestamp,SPEND,electrum:%subaccount:BTC,BTC,%value_without_fee,USD,%fiat_value,%label + comment txid:%oc_hash, notes:%label, taxed_as:SPEND + comment2 %timestamp,SPEND,electrum:%subaccount:BTC,BTC,%oc_amount,USD,%fiat_value,%label if %direction ^OUT$ -& %label (Self|Equity transfer|Capital contribution) - account2 equity:electrum:%subaccount:deposit:BTC - comment txid:%txid, notes:%label, direction:%direction - comment2 -# NOTE: custom rule equity transfers should also clear comment2 +& %ln_amount [1-9] + comment txid:%oc_hash, ln_hash:%ln_hash, notes:%label, direction:%direction, taxed_as:SPEND + comment2 %timestamp,SPEND,electrum:%subaccount:BTC,BTC,%ln_amount,USD,%fiat_value,%label +if %direction ^OUT$ +& %oc_amount ^[^1-9]*$ +& %ln_amount [1-9] + amount -%ln_amount BTC + amount2 %ln_amount BTC + +# Label: lightning channels + +if %direction ^OUT$ +& %label ^Open channel +& %oc_amount [1-9] +& %ln_amount [1-9] + amount -%ln_amount BTC + account2 assets:electrum:%subaccount:ln_locked_payable:BTC + comment2 + +if %direction ^OUT$ +& %label (^sweep local_anchor|^sweep our_ctx_to_local) +& %oc_amount [1-9] +& %ln_amount ^[^1-9]*$ + account2 assets:electrum:%subaccount:BTC + comment + comment2 + +# Treat this OUT as an IN as it's unlocking +if %direction ^OUT$ +& %label ^Close channel +& %oc_hash ^[^a-z0-9]*$ +& %ln_hash ^[^a-z0-9]*$ +& %oc_amount ^[^1-9]*$ +& %ln_amount [1-9] + amount1 -%ln_amount BTC + account1 assets:electrum:%subaccount:ln_locked_payable:BTC + amount2 %ln_amount BTC + account2 assets:electrum:%subaccount:BTC + comment notes:%label, direction:%direction + comment2 + +if %direction ^OUT$ +& %label ^Close channel +& %oc_amount [1-9] +& %ln_amount [1-9] + amount1 -%ln_amount BTC + account1 assets:electrum:%subaccount:ln_locked_payable:BTC + amount2 %ln_amount BTC + account2 assets:electrum:%subaccount:BTC + comment2 + +# Label: transfers +# NOTE: custom rule equity transfers should also clear comment2 +if %direction ^OUT$ +& %label (Self|Transfer|Equity transfer|Capital contribution) + account2 equity:electrum:%subaccount:deposit:BTC + comment txid:%oc_hash, notes:%label, direction:%direction + comment2 + +if %direction ^OUT$ +& %label (Self|Transfer|Equity transfer|Capital contribution) +& %ln_amount [1-9] + comment txid:%oc_hash, ln_hash:%ln_hash, notes:%label, direction:%direction + +# Label: gifts +# TODO: add regex for donate/donation +# TODO: separate donations from gifts subaccount if %direction ^OUT$ & %label Gift account2 expenses:electrum:%subaccount:gifts:BTC - comment txid:%txid, notes:%label, direction:%direction, taxed_as:GIFT - comment2 %timestamp,GIFT,electrum:%subaccount:BTC,BTC,%value_without_fee,USD,%fiat_value,%label + comment txid:%oc_hash, notes:%label, direction:%direction, taxed_as:GIFT + comment2 %timestamp,GIFT,electrum:%subaccount:BTC,BTC,%oc_amount,USD,%fiat_value,%label -# Fees if %direction ^OUT$ -& %fee [1-9] +& %label Gift +& %ln_amount [1-9] + comment txid:%oc_hash, ln_hash:%ln_hash, notes:%label, direction:%direction, taxed_as:GIFT + comment2 %timestamp,GIFT,electrum:%subaccount:BTC,BTC,%ln_amount,USD,%fiat_value,%label + +# +# Fees +# + +if %direction ^OUT$ +& %network_fee [1-9] account3 assets:electrum:%subaccount:BTC - amount3 -%fee BTC + amount3 -%network_fee BTC account4 expenses:electrum:%subaccount:fees:BTC - amount4 %fee BTC - comment txid:%txid, notes:%label, direction:%direction, taxed_as:SPEND - comment3 %timestamp,SPEND,electrum:%subaccount:BTC,BTC,%fee,USD,%fiat_fee,FEE + amount4 %network_fee BTC + comment txid:%oc_hash, notes:%label, direction:%direction, taxed_as:SPEND + comment3 %timestamp,SPEND,electrum:%subaccount:BTC,BTC,%network_fee,USD,%fiat_fee,FEE # Using comment3 so a comment2 SPEND isn't overwritten (when applicable) # vim: sw=2 sts=2 si ai et diff --git a/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/1-in/mockup/2025/electrum-history-wallet-3.csv b/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/1-in/mockup/2025/electrum-history-wallet-3.csv new file mode 100644 index 0000000..6d02ed7 --- /dev/null +++ b/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/1-in/mockup/2025/electrum-history-wallet-3.csv @@ -0,0 +1,13 @@ +oc_transaction_hash,ln_payment_hash,label,confirmations,amount_chain_bc,amount_lightning_bc,fiat_value,network_fee_satoshi,fiat_fee,timestamp +a01c1a2deaa047ef3fd49c01360ddbab88e071a37e85d5446a2a713efa6e5500,,Testnet3 faucet (income),1102,0.00128436,0.,,0,,2025-10-02 19:18:11 +1802953f7f1889fa8034a8170e5b709100f67dad2bae3a110bb80287b53b2811,,Testnet3 faucet (income),1102,0.00168871,0.,,0,,2025-10-02 19:18:11 +db9a16c4661ef161f7bd099ab4c65391dbd6b220055365892ee6958b3d9b431f,,Testnet3 faucet (income),1102,0.00181488,0.,,0,,2025-10-02 19:18:11 +e522cf029812d0b9e7e38e66eb069314b14978d5473faeb7302fdd75366475eb,,Open channel 4735502x1x2,1088,-0.00200634,0.002,0.00,634,,2025-10-02 19:56:35 +fb4c75494cabda8b066d13a5b7d2df4392cd67707ddbf7845ecfff6520a072c2,,Close channel 4735502x1x2,964,0.00198197,-0.002,0.00,1803,,2025-10-03 15:52:55 +f6f208349a6c5bac419bf2258b599526e3ad1b073204c4feee1c8fdd04567fea,,Testnet3 faucet (donate),963,-0.00102797,0.,,2797,,2025-10-03 16:12:56 +6333ecd263e5a2c8e20764ff47a1d95d13257da7593e61244a0a9eacad558af2,,Open channel 4735630x17x2,960,-0.00204941,0.002,0.00,4941,,2025-10-03 17:18:11 +,e801e7b766542f5a2b7e38b0f4bcc585333bc66a0ca35e978157b45c2490f0b5,1 Blockaccino,,0.,-0.00000011,,10,,2025-10-03 19:02:50 +,c77a7035ae00f96a6e054e98412f7dcdebae606dd7e536e249bea76f7dbf3213,1 Scala Chip Frappuccino,,0.,-0.0000505,,50,,2025-10-03 19:04:01 +83f0a0d8bec9e6e549c30b88f3dc50a6f11c9782361c9f394de540925b5b465c,,,933,-0.0000212,0.,,2450,,2025-10-04 00:46:02 +,,Close channel 4735630x17x2,,0.,-0.00194939,,0,,2025-10-04 00:46:02 +4bf6e24b9a6d8f82f7c320a88d667b46c01ccba7bd0bc425417221005c0a9c26,,,205,0.001906,0.,,1572,,2025-10-08 14:03:33 diff --git a/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/electrum-wallet-3.rules b/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/electrum-wallet-3.rules new file mode 100644 index 0000000..c785f18 --- /dev/null +++ b/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/electrum-wallet-3.rules @@ -0,0 +1,20 @@ +# docker-finance | modern accounting for the power-user +# +# Copyright (C) 2021-2025 Aaron Fiore (Founder, Evergreen Crypto LLC) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +include ../../electrum-shared.rules + +# vim: sw=2 sts=2 si ai et diff --git a/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/preprocess b/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/preprocess new file mode 120000 index 0000000..ea94467 --- /dev/null +++ b/container/src/hledger-flow/accounts/electrum/template/electrum/wallet-3/preprocess @@ -0,0 +1 @@ +../../electrum-shared.bash \ No newline at end of file