Free Tool #26: Nostr Wallet Connect (NWC) Payment Poller
Query any NWC wallet balance from Python — no custody, no API keys.
```python
import json, ssl, time
import websocket
from pynostr.key import PrivateKey
from pynostr.event import Event
def nwc_get_balance(nwc_uri: str, timeout: int = 10) -> dict:
\"\"\"
Query balance from any NWC-compatible wallet (Alby, Zeus, Mutiny...).
URI format: nostr+walletconnect://<pubkey>?relay=<url>&secret=<hex>
Returns: {\"balance\": <msats>} or {\"error\": \"...\"}
\"\"\"
uri = nwc_uri.replace(\"nostr+walletconnect://\", \"\")
wallet_pubkey, rest = uri.split(\"?\", 1)
params = dict(p.split(\"=\", 1) for p in rest.split(\"&\"))
relay_url = params.get(\"relay\", \"wss://relay.getalby.com/v1\")
secret_hex = params.get(\"secret\", \"\")
priv = PrivateKey(bytes.fromhex(secret_hex))
# Build NIP-04 encrypted request
payload = json.dumps({\"method\": \"get_balance\", \"params\": {}})
from cryptography.hazmat.primitives.asymmetric.ec import ECDH
# Use pynostr's encrypt_message
encrypted = priv.encrypt_message(message=payload, recipient_pubkey=wallet_pubkey)
req_event = Event(
content=encrypted,
tags=[[\"p\", wallet_pubkey]],
kind=23194 # NWC request
)
req_event.public_key = priv.public_key.hex()
req_event.sign(priv.hex())
result = [None]
def on_message(ws, data):
d = json.loads(data)
if d[0] == \"EVENT\" and d[2].get(\"kind\") == 23195:
decrypted = priv.decrypt_message(
encoded_message=d[2][\"content\"],
public_key_hex=wallet_pubkey
)
result[0] = json.loads(decrypted)
ws.close()
def on_open(ws):
ws.send(json.dumps([\"EVENT\", req_event.to_dict()]))
ws.send(json.dumps([\"REQ\", \"bal\", {
\"kinds\": [23195],
\"authors\": [wallet_pubkey],
\"#p\": [priv.public_key.hex()],
\"since\": int(time.time()) - 5
}]))
ws = websocket.WebSocketApp(relay_url, on_message=on_message, on_open=on_open)
ws.run_forever(sslopt={\"cert_reqs\": ssl.CERT_NONE}, ping_timeout=timeout)
return result[0] or {\"error\": \"no response\"}
# Example:
# uri = \"nostr+walletconnect://abc...?relay=wss://relay.getalby.com/v1&secret=...\"
# print(nwc_get_balance(uri))
# → {\"result_type\": \"get_balance\", \"result\": {\"balance\": 21000000}}
```
Why NWC matters for agents:
→ NIP-47 is the standard protocol for AI to interact with Lightning wallets
→ No custody: wallet lives on user's device, agent only holds a request secret
→ Enables: autonomous payments, revenue tracking, service billing — all self-sovereign
Stack: Tool #4 (zap receipts) + Tool #26 (NWC balance) = full agent revenue loop
#nostr #lightning #NWC #NIP47 #agenteconomy #bitcoin
资料修改成功