dao-treasury 0.0.21__cp311-cp311-win_amd64.whl → 0.0.71__cp311-cp311-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dao-treasury might be problematic. Click here for more details.

Files changed (56) hide show
  1. dao_treasury/.grafana/provisioning/dashboards/breakdowns/Expenses.json +551 -0
  2. dao_treasury/.grafana/provisioning/dashboards/breakdowns/Revenue.json +551 -0
  3. dao_treasury/.grafana/provisioning/dashboards/dashboards.yaml +7 -7
  4. dao_treasury/.grafana/provisioning/dashboards/streams/LlamaPay.json +220 -0
  5. dao_treasury/.grafana/provisioning/dashboards/summary/Monthly.json +286 -29
  6. dao_treasury/.grafana/provisioning/dashboards/transactions/Treasury Transactions.json +217 -84
  7. dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow (Including Unsorted).json +808 -0
  8. dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow.json +602 -0
  9. dao_treasury/.grafana/provisioning/dashboards/treasury/Current Treasury Assets.json +981 -0
  10. dao_treasury/.grafana/provisioning/dashboards/treasury/Historical Treasury Balances.json +3060 -0
  11. dao_treasury/.grafana/provisioning/dashboards/treasury/Operating Cashflow.json +478 -0
  12. dao_treasury/.grafana/provisioning/datasources/datasources.yaml +17 -0
  13. dao_treasury/ENVIRONMENT_VARIABLES.py +20 -0
  14. dao_treasury/__init__.py +20 -0
  15. dao_treasury/_docker.cp311-win_amd64.pyd +0 -0
  16. dao_treasury/_docker.py +67 -38
  17. dao_treasury/_nicknames.cp311-win_amd64.pyd +0 -0
  18. dao_treasury/_nicknames.py +24 -2
  19. dao_treasury/_wallet.cp311-win_amd64.pyd +0 -0
  20. dao_treasury/_wallet.py +157 -16
  21. dao_treasury/constants.cp311-win_amd64.pyd +0 -0
  22. dao_treasury/constants.py +39 -0
  23. dao_treasury/db.py +384 -45
  24. dao_treasury/docker-compose.yaml +6 -5
  25. dao_treasury/main.py +118 -17
  26. dao_treasury/sorting/__init__.cp311-win_amd64.pyd +0 -0
  27. dao_treasury/sorting/__init__.py +171 -42
  28. dao_treasury/sorting/_matchers.cp311-win_amd64.pyd +0 -0
  29. dao_treasury/sorting/_rules.cp311-win_amd64.pyd +0 -0
  30. dao_treasury/sorting/_rules.py +1 -3
  31. dao_treasury/sorting/factory.cp311-win_amd64.pyd +0 -0
  32. dao_treasury/sorting/factory.py +2 -6
  33. dao_treasury/sorting/rule.cp311-win_amd64.pyd +0 -0
  34. dao_treasury/sorting/rule.py +13 -10
  35. dao_treasury/sorting/rules/__init__.cp311-win_amd64.pyd +0 -0
  36. dao_treasury/sorting/rules/__init__.py +1 -0
  37. dao_treasury/sorting/rules/ignore/__init__.cp311-win_amd64.pyd +0 -0
  38. dao_treasury/sorting/rules/ignore/__init__.py +1 -0
  39. dao_treasury/sorting/rules/ignore/llamapay.cp311-win_amd64.pyd +0 -0
  40. dao_treasury/sorting/rules/ignore/llamapay.py +20 -0
  41. dao_treasury/streams/__init__.cp311-win_amd64.pyd +0 -0
  42. dao_treasury/streams/__init__.py +0 -0
  43. dao_treasury/streams/llamapay.cp311-win_amd64.pyd +0 -0
  44. dao_treasury/streams/llamapay.py +388 -0
  45. dao_treasury/treasury.py +79 -30
  46. dao_treasury/types.cp311-win_amd64.pyd +0 -0
  47. dao_treasury-0.0.71.dist-info/METADATA +134 -0
  48. dao_treasury-0.0.71.dist-info/RECORD +54 -0
  49. dao_treasury-0.0.71.dist-info/top_level.txt +2 -0
  50. dao_treasury__mypyc.cp311-win_amd64.pyd +0 -0
  51. 52b51d40e96d4333695d__mypyc.cp311-win_amd64.pyd +0 -0
  52. dao_treasury/.grafana/provisioning/datasources/sqlite.yaml +0 -10
  53. dao_treasury-0.0.21.dist-info/METADATA +0 -63
  54. dao_treasury-0.0.21.dist-info/RECORD +0 -31
  55. dao_treasury-0.0.21.dist-info/top_level.txt +0 -2
  56. {dao_treasury-0.0.21.dist-info → dao_treasury-0.0.71.dist-info}/WHEEL +0 -0
@@ -12,152 +12,290 @@
12
12
  }
13
13
  ]
14
14
  },
15
+ "description": "Summarizes the DAO's monthly profit and loss, providing a breakdown of sorted and unsorted financial activity for each month. Supports financial reporting and tracking the progress of transaction categorization.",
15
16
  "editable": true,
16
17
  "fiscalYearStartMonth": 0,
17
18
  "graphTooltip": 0,
18
- "id": 1,
19
+ "id": 2,
19
20
  "links": [],
20
- "liveNow": false,
21
21
  "panels": [
22
22
  {
23
23
  "datasource": "SQLite",
24
+ "description": "Displays a table of monthly profit and loss for the DAO, including Revenue, Cost of Revenue, Expenses, Other Income, Other Expense, Sorted Net, Unsorted Income, Unsorted Expense.\n\nUseful for high-level financial reporting and tracking the progress of transaction categorization.",
24
25
  "fieldConfig": {
25
26
  "defaults": {
27
+ "color": {
28
+ "mode": "continuous-RdYlGr"
29
+ },
26
30
  "custom": {
27
31
  "align": "auto",
28
32
  "cellOptions": {
29
33
  "type": "auto"
30
34
  },
31
- "inspect": false
35
+ "footer": {
36
+ "reducers": ["sum", "max", "mean", "median"]
37
+ },
38
+ "inspect": true
32
39
  },
40
+ "fieldMinMax": true,
41
+ "links": [
42
+ {
43
+ "targetBlank": true,
44
+ "title": "View ${__field.name} transactions for this period",
45
+ "url": "/d/b21f1092-66a4-4fb0-90ef-ed77d2becaa4/treasury-transactions?var-Top=${__field.name}&from=${__data.fields.month_start}&to=${__data.fields.month_end}"
46
+ }
47
+ ],
33
48
  "mappings": [],
34
49
  "thresholds": {
35
50
  "mode": "absolute",
36
51
  "steps": [
37
52
  {
38
53
  "color": "green",
39
- "value": null
54
+ "value": 0
40
55
  },
41
56
  {
42
57
  "color": "red",
43
58
  "value": 80
44
59
  }
45
60
  ]
46
- }
61
+ },
62
+ "unit": "currencyUSD"
47
63
  },
48
64
  "overrides": [
49
65
  {
50
66
  "matcher": {
51
67
  "id": "byName",
52
- "options": "hash"
68
+ "options": "Sorted Net"
69
+ },
70
+ "properties": [
71
+ {
72
+ "id": "custom.cellOptions",
73
+ "value": {
74
+ "type": "color-text"
75
+ }
76
+ },
77
+ {
78
+ "id": "links"
79
+ }
80
+ ]
81
+ },
82
+ {
83
+ "matcher": {
84
+ "id": "byName",
85
+ "options": "Net"
86
+ },
87
+ "properties": [
88
+ {
89
+ "id": "custom.cellOptions",
90
+ "value": {
91
+ "type": "color-text"
92
+ }
93
+ },
94
+ {
95
+ "id": "links"
96
+ }
97
+ ]
98
+ },
99
+ {
100
+ "matcher": {
101
+ "id": "byName",
102
+ "options": "Unsorted Income"
103
+ },
104
+ "properties": [
105
+ {
106
+ "id": "custom.cellOptions",
107
+ "value": {
108
+ "type": "color-text"
109
+ }
110
+ },
111
+ {
112
+ "id": "color",
113
+ "value": {
114
+ "mode": "fixed"
115
+ }
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "matcher": {
121
+ "id": "byName",
122
+ "options": "Unsorted Expenses"
123
+ },
124
+ "properties": [
125
+ {
126
+ "id": "custom.cellOptions",
127
+ "value": {
128
+ "type": "color-text"
129
+ }
130
+ },
131
+ {
132
+ "id": "color",
133
+ "value": {
134
+ "mode": "fixed"
135
+ }
136
+ }
137
+ ]
138
+ },
139
+ {
140
+ "matcher": {
141
+ "id": "byName",
142
+ "options": "Other Income"
53
143
  },
54
144
  "properties": [
55
145
  {
56
- "id": "links",
57
- "value": [
58
- {
59
- "targetBlank": true,
60
- "title": "View on Etherscan",
61
- "url": "https://etherscan.io/tx/${__value.raw}"
62
- }
63
- ]
146
+ "id": "custom.cellOptions",
147
+ "value": {
148
+ "type": "color-text"
149
+ }
150
+ },
151
+ {
152
+ "id": "color",
153
+ "value": {
154
+ "mode": "fixed"
155
+ }
64
156
  }
65
157
  ]
66
158
  },
67
159
  {
68
160
  "matcher": {
69
161
  "id": "byName",
70
- "options": "block"
162
+ "options": "Other Expenses"
71
163
  },
72
164
  "properties": [
73
165
  {
74
- "id": "links",
75
- "value": [
76
- {
77
- "targetBlank": true,
78
- "title": "View on Etherscan",
79
- "url": "https://etherscan.io/block/${__value.raw}"
80
- }
81
- ]
166
+ "id": "custom.cellOptions",
167
+ "value": {
168
+ "type": "color-text"
169
+ }
170
+ },
171
+ {
172
+ "id": "color",
173
+ "value": {
174
+ "mode": "fixed"
175
+ }
82
176
  }
83
177
  ]
84
178
  },
85
179
  {
86
180
  "matcher": {
87
181
  "id": "byName",
88
- "options": "to"
182
+ "options": "Operating Net"
89
183
  },
90
184
  "properties": [
91
185
  {
92
- "id": "links",
93
- "value": [
94
- {
95
- "targetBlank": true,
96
- "title": "View on Etherscan",
97
- "url": "https://etherscan.io/address/${__value.raw}"
98
- }
99
- ]
186
+ "id": "custom.cellOptions",
187
+ "value": {
188
+ "type": "color-text"
189
+ }
190
+ },
191
+ {
192
+ "id": "color",
193
+ "value": {
194
+ "mode": "continuous-RdYlGr"
195
+ }
196
+ },
197
+ {
198
+ "id": "links"
100
199
  }
101
200
  ]
102
201
  },
103
202
  {
104
203
  "matcher": {
105
204
  "id": "byName",
106
- "options": "from"
205
+ "options": "month_start"
107
206
  },
108
207
  "properties": [
109
208
  {
110
- "id": "links",
111
- "value": [
112
- {
113
- "targetBlank": true,
114
- "title": "View on Etherscan",
115
- "url": "https://etherscan.io/address/${__value.raw}"
116
- }
117
- ]
209
+ "id": "unit"
210
+ },
211
+ {
212
+ "id": "custom.hideFrom.viz",
213
+ "value": true
118
214
  }
119
215
  ]
120
216
  },
121
217
  {
122
218
  "matcher": {
123
219
  "id": "byName",
124
- "options": "from nickname"
220
+ "options": "month_end"
125
221
  },
126
222
  "properties": [
127
223
  {
128
- "id": "links",
129
- "value": [
130
- {
131
- "targetBlank": true,
132
- "title": "View on Etherscan",
133
- "url": "https://etherscan.io/address/${__data.fields.from}"
134
- }
135
- ]
224
+ "id": "unit"
225
+ },
226
+ {
227
+ "id": "custom.hideFrom.viz",
228
+ "value": true
136
229
  }
137
230
  ]
138
231
  },
139
232
  {
140
233
  "matcher": {
141
234
  "id": "byName",
142
- "options": "to nickname"
235
+ "options": "Revenue"
143
236
  },
144
237
  "properties": [
145
238
  {
146
- "id": "links",
147
- "value": [
148
- {
149
- "targetBlank": true,
150
- "title": "View on Etherscan",
151
- "url": "https://etherscan.io/address/${__data.fields.to}"
152
- }
153
- ]
239
+ "id": "custom.cellOptions",
240
+ "value": {
241
+ "type": "color-text"
242
+ }
243
+ },
244
+ {
245
+ "id": "color",
246
+ "value": {
247
+ "fixedColor": "#ffffff",
248
+ "mode": "fixed"
249
+ }
250
+ }
251
+ ]
252
+ },
253
+ {
254
+ "matcher": {
255
+ "id": "byName",
256
+ "options": "Expenses"
257
+ },
258
+ "properties": [
259
+ {
260
+ "id": "custom.cellOptions",
261
+ "value": {
262
+ "type": "color-text"
263
+ }
264
+ },
265
+ {
266
+ "id": "color",
267
+ "value": {
268
+ "fixedColor": "#ffffff",
269
+ "mode": "fixed"
270
+ }
271
+ }
272
+ ]
273
+ },
274
+ {
275
+ "matcher": {
276
+ "id": "byName",
277
+ "options": "Cost of Revenue"
278
+ },
279
+ "properties": [
280
+ {
281
+ "id": "color",
282
+ "value": {
283
+ "fixedColor": "#ffffff",
284
+ "mode": "fixed"
285
+ }
286
+ },
287
+ {
288
+ "id": "custom.cellOptions",
289
+ "value": {
290
+ "type": "color-text"
291
+ }
154
292
  }
155
293
  ]
156
294
  }
157
295
  ]
158
296
  },
159
297
  "gridPos": {
160
- "h": 18,
298
+ "h": 20,
161
299
  "w": 24,
162
300
  "x": 0,
163
301
  "y": 0
@@ -165,48 +303,43 @@
165
303
  "id": 1,
166
304
  "options": {
167
305
  "cellHeight": "sm",
168
- "footer": {
169
- "countRows": false,
170
- "fields": "",
171
- "reducer": [
172
- "sum"
173
- ],
174
- "show": false
175
- },
176
- "showHeader": true
306
+ "showHeader": true,
307
+ "sortBy": [
308
+ {
309
+ "desc": true,
310
+ "displayName": "Month"
311
+ }
312
+ ]
177
313
  },
178
- "pluginVersion": "10.2.0",
314
+ "pluginVersion": "12.2.1",
179
315
  "targets": [
180
316
  {
181
317
  "datasource": "SQLite",
182
- "queryText": "select chain_name as chain, timestamp, block, hash, token, \"from\", from_nickname as \"from nickname\", \"to\", to_nickname as \"to nickname\", amount, price, value_usd as \"value usd\", txgroup, parent_txgroup\nfrom (\n SELECT treasury_tx_id, b.chain_name, datetime(a.timestamp, 'unixepoch') AS timestamp, a.block, a.hash, a.log_index, c.symbol AS token, d.address AS \"from\", d.nickname as from_nickname, e.address AS \"to\", e.nickname as to_nickname, a.amount, a.price, a.value_usd, f.name AS txgroup, g.name AS parent_txgroup, f.txgroup_id\n FROM treasury_txs a\n LEFT JOIN chains b ON a.chain = b.chain_dbid\n LEFT JOIN tokens c ON a.token_id = c.token_id\n LEFT JOIN addresses d ON a.\"from\" = d.address_id\n LEFT JOIN addresses e ON a.\"to\" = e.address_id\n LEFT JOIN txgroups f ON a.txgroup_id = f.txgroup_id\n LEFT JOIN txgroups g ON f.parent_txgroup = g.txgroup_id\n WHERE a.timestamp >= $__from / 1000 and a.timestamp < $__to / 1000\n --UNION\n --SELECT -1, chain_name, TIMESTAMP, cast(block AS integer) block, hash, CAST(log_index AS integer) as log_index, token, \"from\", from_nickname, \"to\", to_nickname, amount, price, value_usd, txgroup, parent_txgroup, txgroup_id\n --FROM stream_ledger\n --UNION\n --SELECT -1, *\n --FROM vesting_ledger \n) a\nORDER BY timestamp",
318
+ "queryText": "SELECT\n month AS \"Month\",\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END) AS \"Revenue\",\n SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END) AS \"Cost of Revenue\",\n SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END) AS \"Expenses\",\n (\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END)\n ) AS \"Operating Net\",\n SUM(CASE WHEN s.top_category = 'Other Income' THEN value_usd ELSE 0 END) AS \"Other Income\",\n SUM(CASE WHEN s.top_category = 'Other Expenses' THEN value_usd ELSE 0 END) AS \"Other Expenses\",\n (\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END)\n + SUM(CASE WHEN s.top_category = 'Other Income' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Other Expenses' THEN value_usd ELSE 0 END)\n ) AS \"Sorted Net\",\n SUM(CASE WHEN s.top_category = 'Sort Me (Inbound)' THEN value_usd ELSE 0 END) AS \"Unsorted Income\",\n SUM(CASE WHEN s.top_category = 'Sort Me (Outbound)' THEN value_usd ELSE 0 END) AS \"Unsorted Expenses\",\n (\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END)\n + SUM(CASE WHEN s.top_category = 'Other Income' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Other Expenses' THEN value_usd ELSE 0 END)\n + SUM(CASE WHEN s.top_category = 'Sort Me (Inbound)' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Sort Me (Outbound)' THEN value_usd ELSE 0 END)\n ) AS \"Net\",\n -- Month Start as UNIX timestamp (midnight on the first day)\n CAST(strftime('%s', month || '-01') * 1000 AS TEXT) AS \"month_start\",\n -- Month End as UNIX timestamp (one millisecond before the next month starts)\n CAST(strftime('%s', date(month || '-01', '+1 month')) * 1000 - 1 AS TEXT) AS \"month_end\"\nFROM (\n SELECT\n strftime('%Y-%m', datetime(t.timestamp, 'unixepoch')) AS month,\n gh.top_category,\n COALESCE(t.value_usd, 0) AS value_usd\n FROM treasury_txs AS t\n JOIN txgroups AS tg ON t.txgroup_id = tg.txgroup_id\n JOIN txgroup_hierarchy AS gh ON tg.txgroup_id = gh.txgroup_id\n WHERE t.timestamp >= strftime('%s', '2025-01-01') AND tg.name <> 'Ignore'\n) AS s\nGROUP BY month;",
183
319
  "queryType": "table",
184
- "rawQueryText": "select chain_name as chain, timestamp, block, hash, token, \"from\", from_nickname as \"from nickname\", \"to\", to_nickname as \"to nickname\", amount, price, value_usd as \"value usd\", txgroup, parent_txgroup\nfrom (\n SELECT treasury_tx_id, b.chain_name, datetime(a.timestamp, 'unixepoch') AS timestamp, a.block, a.hash, a.log_index, c.symbol AS token, d.address AS \"from\", d.nickname as from_nickname, e.address AS \"to\", e.nickname as to_nickname, a.amount, a.price, a.value_usd, f.name AS txgroup, g.name AS parent_txgroup, f.txgroup_id\n FROM treasury_txs a\n LEFT JOIN chains b ON a.chain = b.chain_dbid\n LEFT JOIN tokens c ON a.token_id = c.token_id\n LEFT JOIN addresses d ON a.\"from\" = d.address_id\n LEFT JOIN addresses e ON a.\"to\" = e.address_id\n LEFT JOIN txgroups f ON a.txgroup_id = f.txgroup_id\n LEFT JOIN txgroups g ON f.parent_txgroup = g.txgroup_id\n WHERE a.timestamp >= $__from / 1000 and a.timestamp < $__to / 1000\n --UNION\n --SELECT -1, chain_name, TIMESTAMP, cast(block AS integer) block, hash, CAST(log_index AS integer) as log_index, token, \"from\", from_nickname, \"to\", to_nickname, amount, price, value_usd, txgroup, parent_txgroup, txgroup_id\n --FROM stream_ledger\n --UNION\n --SELECT -1, *\n --FROM vesting_ledger \n) a\nORDER BY timestamp",
320
+ "rawQueryText": "SELECT\n month AS \"Month\",\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END) AS \"Revenue\",\n SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END) AS \"Cost of Revenue\",\n SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END) AS \"Expenses\",\n (\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END)\n ) AS \"Operating Net\",\n SUM(CASE WHEN s.top_category = 'Other Income' THEN value_usd ELSE 0 END) AS \"Other Income\",\n SUM(CASE WHEN s.top_category = 'Other Expenses' THEN value_usd ELSE 0 END) AS \"Other Expenses\",\n (\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END)\n + SUM(CASE WHEN s.top_category = 'Other Income' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Other Expenses' THEN value_usd ELSE 0 END)\n ) AS \"Sorted Net\",\n SUM(CASE WHEN s.top_category = 'Sort Me (Inbound)' THEN value_usd ELSE 0 END) AS \"Unsorted Income\",\n SUM(CASE WHEN s.top_category = 'Sort Me (Outbound)' THEN value_usd ELSE 0 END) AS \"Unsorted Expenses\",\n (\n SUM(CASE WHEN s.top_category = 'Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Cost of Revenue' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Expenses' THEN value_usd ELSE 0 END)\n + SUM(CASE WHEN s.top_category = 'Other Income' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Other Expenses' THEN value_usd ELSE 0 END)\n + SUM(CASE WHEN s.top_category = 'Sort Me (Inbound)' THEN value_usd ELSE 0 END)\n - SUM(CASE WHEN s.top_category = 'Sort Me (Outbound)' THEN value_usd ELSE 0 END)\n ) AS \"Net\",\n -- Month Start as UNIX timestamp (midnight on the first day)\n CAST(strftime('%s', month || '-01') * 1000 AS TEXT) AS \"month_start\",\n -- Month End as UNIX timestamp (one millisecond before the next month starts)\n CAST(strftime('%s', date(month || '-01', '+1 month')) * 1000 - 1 AS TEXT) AS \"month_end\"\nFROM (\n SELECT\n strftime('%Y-%m', datetime(t.timestamp, 'unixepoch')) AS month,\n gh.top_category,\n COALESCE(t.value_usd, 0) AS value_usd\n FROM treasury_txs AS t\n JOIN txgroups AS tg ON t.txgroup_id = tg.txgroup_id\n JOIN txgroup_hierarchy AS gh ON tg.txgroup_id = gh.txgroup_id\n WHERE t.timestamp >= strftime('%s', '2025-01-01') AND tg.name <> 'Ignore'\n) AS s\nGROUP BY month;",
185
321
  "refId": "A",
186
- "timeColumns": [
187
- "time",
188
- "ts"
189
- ]
322
+ "timeColumns": ["time", "ts"]
190
323
  }
191
324
  ],
192
- "title": "Transactions",
325
+ "title": "Monthly Profit & Loss",
193
326
  "type": "table"
194
327
  }
195
328
  ],
329
+ "preload": false,
196
330
  "refresh": "",
197
- "schemaVersion": 38,
331
+ "schemaVersion": 42,
198
332
  "tags": [],
199
333
  "templating": {
200
334
  "list": []
201
335
  },
202
336
  "time": {
203
- "from": "now-7d",
337
+ "from": "now/y",
204
338
  "to": "now"
205
339
  },
206
340
  "timepicker": {},
207
341
  "timezone": "",
208
- "title": "Treasury Transactions",
209
- "uid": "b21f1092-66a4-4fb0-90ef-ed77d2becaa4",
210
- "version": 5,
211
- "weekStart": ""
212
- }
342
+ "title": "Monthly P&L",
343
+ "uid": "a63fa9a7-d4f3-4092-9bde-194add8bcbeb",
344
+ "version": 7
345
+ }