Vote for Brianoflondon's Witness KeyChain or HiveSigner
Support Proposal 342 on PeakD
This is a value for value post: see the explanation in the footer.
Using Custom Json on Hive to Interact with Keepsats
What's New
Previously on the old system, it was pretty much impossible to do anything with a Keepsats balance on the system without using the front end website. Technically there was an authentication protocol and whilst I didn't make it a secret, nobody ever looked at it.
But with the v2 system which went live last week, I've had a major change in internal architecture and that gives a new way to interact with the system: you can move Keepsats around with custom_json transactions on the Hive blockchain.
If you want help using this or talk to me about this, best option is to comment under this post and we can chat in public. If you want a direct line to me, Telegram is the best bet.
Background
There are two main ways to deposit Keepsats on the v4v.app system: send a Hive or HBD transfer to the server Hive account with #sats anywhere in the memo, or receive lightning on a Lightning address on the system (e.g. brianoflondon@sats.v4v.app).
Paying a Lightning Invoice with Keepsats
Using the Web
The web‑based app on v4v.app allows you to spend Keepsats directly.
Custom Json
External users can interact with the v4v.app backend by submitting a Hive custom_json operation. The operation must be signed with the active key of the from_account and the JSON payload must include from_account matching that authority. This requirement protects against replay attacks and ensures the sender consents to the action.
There are three distinct behaviours the system recognises based on the fields you supply:
- Keepsats transfer between two v4v accounts
- Send sats to a Lightning address
- Pay a Lightning invoice
All of the custom‑json operations use the same id value: v4vapp_transfer.
1. Transfer Keepsats (on‑chain balance move)
Use this when you simply want to move sats from one v4v user to another.
{
"id": "v4vapp_transfer",
"json": {
"from_account": "alice",
"to_account": "bob",
"sats": 500000,
"memo": "thanks for the coffee"
}
}
from_account– must match the active authority of the transaction.to_account– the Hive account that will receive the sats. This account must already be registered with the v4v system (i.e. has a keepsats balance).satsormsats– the amount to transfer from sender to receiver.msatsare milisatoshis, 1/1000ths of a sat. If you specifymsatsthensatsvalue will be ignored. All internal accounting is actually inmsats.memo– optional free‑form text stored with the transfer.
The backend debits from_account's keepsats balance and credits to_account accordingly.
1a. Converting keepsats to Hive/HBD via transfer to the server
If you transfer keepsats to the server account itself (e.g. v4vapp), the backend will interpret the operation as a conversion request. The sats will be exchanged for Hive or HBD based on the memo contents. A #HBD tag forces HBD, otherwise the default is Hive.
The custom JSON payload is identical to a normal transfer but uses the v4vapp_dev_transfer ID when working against a development instance. It must be signed with the active key of the sending account.
Example:
{
"id": "v4vapp_transfer",
"json": {
"from_account": "brianoflondon",
"to_account": "v4vapp",
"sats": 1234,
"memo": "Converting sats to #HIVE"
}
}
from_account– must match the active authority of the transaction.to_account– the server account receiving the sats for conversion.satsormsats– amount to convert.memo– include#HIVEor#HBDto specify the destination asset (default is Hive).
2. Send to a Lightning Address
This lets an external user withdraw sats from their keepsats balance and push them to any Lightning address.
{
"id": "v4vapp_transfer",
"json": {
"from_account": "alice",
"to_account": "v4vapp",
"memo": "bob@sats.v4v.app",
"sats": 200000
}
}
to_account- in order to pay a lightning address, theto_accountmust be the server in this casev4vapp.memo– a Lightning address (for exampleuser@sats.v4v.app).sats(ormsats) – the amount to send. The system will attempt to route the payment for exactly this amount.
The to_account must be the v4vapp server account – sats are pulled from the sender's balance and forwarded on‑chain via LND. The from_account requirement still applies.
3. Pay a Lightning Invoice
When the memo field contains a BOLT‑11 invoice, the system will try to settle that invoice on behalf of the from_account. The invoice itself encodes the amount, so you must not supply sats in the JSON unless you want to impose an upper limit on the invoice value (see below).
{
"id": "v4vapp_transfer",
"json": {
"from_account": "alice",
"to_account": "v4vapp",
"memo": "lnbc1...",
"sats": 100000 # optional limit, invoice must be <= this
}
}
to_account- in order to pay a lightning address, theto_accountmust be the server in this casev4vapp.memo– full Lightning invoice string. The amount is fixed inside the invoice.sats/msats– optional. If provided, the invoice amount cannot exceed this value; otherwise the request is rejected.
The to_account field needs to be v4vapp the server account.
The backend pays the invoice using the sender's keepsats balance.
Additional notes
- If both a Lightning address and an invoice are supplied in
memo, the system treats it as an invoice and ignores the address. - For any request that sends sats outside the v4v ledger (cases 2 and 3 above), the
to_accountfield is not required and is ignored if present. - All custom JSON operations must be broadcast as a Hive transaction signed by the active key of
from_account. Unsigned or improperly signed operations are rejected. - Amounts are denominated in satoshis. Use
msatsif you require millisecond precision.
By structuring your custom_json payload according to one of the patterns above you can automate deposits and withdrawals without ever touching the web interface.
System‑generated notifications
Any time the backend needs to inform you about the status of a previous operation it will send back a notification custom JSON. These are not submitted by users – they are sent from the server account and carry details of errors, refunds, conversion results, or other informational messages.
- ID –
PREFIX_notification(e.g.v4vapp_notificationon production). - from_account – always the server’s Hive account name.
- to_account – the original requesting
from_account. - memo – human‑readable message describing what happened. Errors such as “Insufficient Keepsats balance” are common.
- msats – zero for pure notifications; if the notification accompanies a transfer it will contain the amount that was moved.
- parent_id – group id of the original operation, useful for tracing.
- notification – boolean flag set to
true.
Example of a failure notice returned when a user’s invoice payment could not be completed:
{
"id": "v4vapp_notification",
"json": {
"from_account": "v4vapp",
"to_account": "alice",
"memo": "Insufficient Keepsats balance | § XYZ123",
"msats": 0,
"parent_id": "XYZ123",
"notification": true
}
}
You can monitor Hive operations for notifications if you wish to automate logging or alerts. They are purely informational – the system does not attempt to act on them further but they will be stored in the ledger under the CUSTOM_JSON_TRANSFER/CUSTOM_JSON_FEE types depending on context.
Notifications are also generated for successful replies when the backend performs a conversion or other return and chooses to send a result via custom json rather than a Hive transfer. These replies follow the same format, with a non‑zero msats when sats are being returned.
Value for Value
For the last few months while building I was generously supported by the DHF. Going forward I have a much more modest support which covers direct server costs and a little of my time.
If you appreciate the work I do on and around Hive, you can express this directly: upvoting posts on Hive is great. Also consider a direct donation (there's a Tip button on Hive or a Lightning Address) on all my posts.

Support Proposal 342 on PeakD
Support Proposal 342 with Hivesigner
Support Proposal 342 on Ecency
Vote for Brianoflondon's Witness KeyChain or HiveSigner