SubscribeWallet
SubscribeWallet streams activity updates as they happen. The stream is resumable: each response carries a monotonic cursor the client can reconnect from to replay everything after it without gaps.
Endpoints
rpc SubscribeWallet(SubscribeWalletRequest) returns (stream SubscribeWalletResponse)POST/v1/wallet/subscribeExamples
conn, err := grpc.NewClient("localhost:10029",
grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := wavewalletrpc.NewWalletServiceClient(conn)
ctx := context.Background()
req := &wavewalletrpc.SubscribeWalletRequest{
IncludeExisting: true,
}
stream, err := client.SubscribeWallet(ctx, req)
if err != nil {
log.Fatal(err)
}
for {
update, err := stream.Recv()
if err != nil {
break
}
fmt.Println(update)
}conn, err := grpc.NewClient("localhost:10029",
grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := wavewalletrpc.NewWalletServiceClient(conn)
ctx := context.Background()
req := &wavewalletrpc.SubscribeWalletRequest{
IncludeExisting: true,
}
stream, err := client.SubscribeWallet(ctx, req)
if err != nil {
log.Fatal(err)
}
for {
update, err := stream.Recv()
if err != nil {
break
}
fmt.Println(update)
}import grpc
import wallet_pb2
import wallet_pb2_grpc
channel = grpc.insecure_channel('localhost:10029')
stub = wallet_pb2_grpc.WalletServiceStub(channel)
request = wallet_pb2.SubscribeWalletRequest(
include_existing=True,
)
for update in stub.SubscribeWallet(request):
print(update)const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync('wallet.proto');
const { wavewalletrpc } = grpc.loadPackageDefinition(packageDefinition);
const client = new wavewalletrpc.WalletService(
'localhost:10029',
grpc.credentials.createInsecure(),
);
const request = {
"include_existing": true
};
// Calls wavewalletrpc.WalletService.SubscribeWallet.
const stream = client.subscribeWallet(request);
stream.on('data', (update) => console.log(update));
stream.on('end', () => console.log('stream closed'));curl -X POST http://localhost:10031/v1/wallet/subscribe \
-H 'Content-Type: application/json' \
-d '{"include_existing":true}'const res = await fetch('http://localhost:10031/v1/wallet/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"include_existing": true
}),
});
// The gateway streams newline-delimited JSON objects.
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
for (;;) {
const { value, done } = await reader.read();
if (done) break;
for (const line of value.split('\n').filter(Boolean)) {
console.log(JSON.parse(line));
}
}RequestSubscribeWalletRequest
SubscribeWalletRequest configures the WalletService.SubscribeWallet stream.
| Field | Type | Description |
|---|---|---|
include_existing | bool | include_existing replays the full activity history before live updates. It is ignored when cursor is set (cursor already selects the replay start). |
kinds | repeated EntryKind | kinds optionally narrows the stream to specific entry categories. When empty, all kinds are streamed. |
cursor | int64 | cursor resumes the stream from a prior SubscribeWalletResponse.cursor: the daemon replays every event after it, then continues live. Zero (unset) starts from the full history when include_existing is set, or from the current tip otherwise. |
Responsestream SubscribeWalletResponse
SubscribeWalletResponse is one item in the SubscribeWallet stream: either a projected activity row or a gap signal telling the subscriber it fell behind and must reconcile.
| Field | Type | Description |
|---|---|---|
cursor | int64 | cursor is the monotonic event-log position of this update. A client persists it and reconnects with SubscribeWalletRequest.cursor set to the last value it processed to resume without gaps. The sequence is monotonic but NOT contiguous: a value may be skipped, so a client treats any cursor past its last as new and never infers a dropped event from a gap in the numbers. |
entryoneof update | WalletEntry | entry is a projected activity row at cursor. |
gaponeof update | SubscribeGap | gap signals the subscriber fell behind the live buffer and should reconcile current state via List, then resume from cursor. |
EntryKindenum
EntryKind tags each WalletEntry with the user-visible category of the underlying operation. Internal subtypes (same-Ark p2p vs real Lightning, OOR session correlators, round IDs) are deliberately not surfaced.
| Name | Number | Description |
|---|---|---|
ENTRY_KIND_UNSPECIFIED | 0 | ENTRY_KIND_UNSPECIFIED is the proto zero value used when the operation category is unknown. |
ENTRY_KIND_SEND | 1 | ENTRY_KIND_SEND is an outbound payment over any rail (Lightning, same-Ark, onchain, or credit). |
ENTRY_KIND_RECV | 2 | ENTRY_KIND_RECV is an inbound receive. |
ENTRY_KIND_DEPOSIT | 3 | ENTRY_KIND_DEPOSIT is a boarding deposit rolled into a VTXO. |
ENTRY_KIND_EXIT | 4 | ENTRY_KIND_EXIT is a cooperative leave or unilateral exit to on-chain funds. |
WalletEntrymessage
WalletEntry is the single flat row type returned by the ACTIVITY view of List and by SubscribeWallet. The shape is deliberately minimal: display clients should be able to render kind/status/amount/fee/phase directly without parsing daemon-specific swap or ledger internals. Power-user detail belongs in WalletInspectionService.InspectActivity.
| Field | Type | Description |
|---|---|---|
id | string | id is the stable identifier for this entry. Swap-backed SEND and RECV rows use the Lightning payment_hash. Credit-backed RECV rows use the credit operation id (see CreditReceive.operation_id); the payment_hash lives on recv progress/detail instead. EXIT rows use leave_job_id (or sweep txid); DEPOSIT rows use the boarding outpoint or txid. |
kind | EntryKind | kind is the user-visible category. |
status | EntryStatus | status is the coarse user-facing outcome: PENDING, COMPLETE, or FAILED. It mirrors the backing source's durable state and should not be reinterpreted by display clients. |
amount_sat | int64 | amount_sat is signed: positive values are incoming to the wallet, negative values are outgoing. |
fee_sat | int64 | fee_sat is the absolute fee paid (or pending) for this operation. |
counterparty | string | counterparty is a short, display-friendly identifier of the other side: a truncated invoice for Lightning, an ark peer address for OOR, a bech32 onchain address for exits, or "boarding" for deposits. |
created_at_unix | int64 | created_at_unix is the local creation timestamp in unix seconds. |
updated_at_unix | int64 | updated_at_unix is the last persisted update timestamp in unix seconds. List ACTIVITY and SubscribeWallet sort by this field, descending. |
note | string | note is the caller-supplied label captured at submit time, if any. |
failure_reason | string | failure_reason is populated only when status is FAILED. It is a single human-readable string, never a coded enum tree. |
request | WalletEntryRequest | request is the original payment request or destination associated with the entry, when the backing subsystem persists it. This is useful for expanded views and inspection; compact clients should not need to parse it to explain status or lifecycle. |
progress | WalletEntryProgress | progress carries lifecycle-specific metadata already normalized by the wallet service. Clients can render phase_label directly or switch on phase without inferring meaning from swap/ledger internals. |
failure_codeoptional | EntryFailureCode | failure_code is a stable, machine-readable classification of why a FAILED entry failed. It is set ONLY on FAILED entries; a non-failed entry omits the field entirely (presence-tracked), so its absence is the canonical "no failure" signal and ENTRY_FAILURE_CODE_UNSPECIFIED is never sent on the wire. failure_reason remains the human-readable supplement. |
EntryStatusenum
EntryStatus collapses every backing FSM into the three states user-facing surfaces actually need.
| Name | Number | Description |
|---|---|---|
ENTRY_STATUS_UNSPECIFIED | 0 | ENTRY_STATUS_UNSPECIFIED is the proto zero value used when the backing state has not been mapped yet. |
ENTRY_STATUS_PENDING | 1 | ENTRY_STATUS_PENDING means the operation is still in flight. |
ENTRY_STATUS_COMPLETE | 2 | ENTRY_STATUS_COMPLETE means the operation reached a durable success state. |
ENTRY_STATUS_FAILED | 3 | ENTRY_STATUS_FAILED means the operation reached a terminal failure state. |
WalletEntryRequestmessage
WalletEntryRequest describes the user-recognizable request that created a WalletEntry. It is a oneof because each operation is backed by exactly one request shape.
| Field | Type | Description |
|---|---|---|
lightning_invoiceoneof request | LightningInvoiceRequest | lightning_invoice is populated for Lightning send and receive entries. |
onchain_addressoneof request | OnchainAddressRequest | onchain_address is populated for deposit and exit entries. |
ark_addressoneof request | ArkAddressRequest | ark_address is populated for direct Ark send or receive entries. |
LightningInvoiceRequestmessage
LightningInvoiceRequest captures the Lightning request associated with an activity entry.
| Field | Type | Description |
|---|---|---|
invoice | string | invoice is the BOLT-11 payment request. |
payment_hash | string | payment_hash identifies the invoice and remains stable after the invoice itself is no longer convenient to display. |
OnchainAddressRequestmessage
OnchainAddressRequest captures the onchain address associated with an activity entry.
| Field | Type | Description |
|---|---|---|
address | string | address is the bech32 onchain address originally issued or targeted. |
ArkAddressRequestmessage
ArkAddressRequest captures the Ark address associated with an activity entry.
| Field | Type | Description |
|---|---|---|
address | string | address is the Ark address originally issued or targeted. |
WalletEntryProgressmessage
WalletEntryProgress carries lifecycle metadata normalized by the wallet service.
| Field | Type | Description |
|---|---|---|
phase | WalletEntryPhase | phase is the coarse lifecycle phase for this entry. |
phase_label | string | phase_label is a short lowercase label that clients can render as-is while they migrate to enum-based presentation. |
payment_hash | string | payment_hash is populated for Lightning-backed send/recv entries. |
txid | string | txid is populated when the backing ledger row has an onchain txid. |
confirmation_height | int32 | confirmation_height is populated once the source records it. |
vtxo_outpoint | string | vtxo_outpoint is populated when a swap observes the Ark vHTLC output. |
preimage | string | preimage is the hex-encoded Lightning payment preimage once the swap revealed it. For a completed Lightning-backed send this is the proof of payment for the paid invoice (sha256(preimage) == payment_hash); it is empty until the preimage is durably known and for non-Lightning entries. |
WalletEntryPhaseenum
WalletEntryPhase is a coarse, wallet-facing lifecycle phase. It is not a replacement for status; status answers whether the operation is pending, complete, or failed, while phase explains the current backing-system step.
| Name | Number | Description |
|---|---|---|
WALLET_ENTRY_PHASE_UNSPECIFIED | 0 | WALLET_ENTRY_PHASE_UNSPECIFIED is the proto zero value used when the backing subsystem has no lifecycle hint. |
WALLET_ENTRY_PHASE_REQUEST_CREATED | 1 | WALLET_ENTRY_PHASE_REQUEST_CREATED means the request was created but no payment has been observed. |
WALLET_ENTRY_PHASE_WAITING_FOR_PAYMENT | 2 | WALLET_ENTRY_PHASE_WAITING_FOR_PAYMENT means the wallet is waiting for an inbound payment or swap funding. |
WALLET_ENTRY_PHASE_PAYMENT_DETECTED | 3 | WALLET_ENTRY_PHASE_PAYMENT_DETECTED means the backing subsystem has detected a payment but it is not yet settled. |
WALLET_ENTRY_PHASE_SETTLING | 4 | WALLET_ENTRY_PHASE_SETTLING means the operation is being settled through Ark, Lightning, or onchain machinery. |
WALLET_ENTRY_PHASE_CONFIRMED | 5 | WALLET_ENTRY_PHASE_CONFIRMED means the backing operation is confirmed or otherwise durably complete. |
WALLET_ENTRY_PHASE_REFUNDING | 6 | WALLET_ENTRY_PHASE_REFUNDING means the operation is currently refunding. |
WALLET_ENTRY_PHASE_REFUNDED | 7 | WALLET_ENTRY_PHASE_REFUNDED means the refund path completed. |
WALLET_ENTRY_PHASE_FAILED | 8 | WALLET_ENTRY_PHASE_FAILED means the backing operation reached a terminal failed state. |
WALLET_ENTRY_PHASE_WAITING_FOR_CONFIRMATION | 9 | WALLET_ENTRY_PHASE_WAITING_FOR_CONFIRMATION means an onchain payment has been detected and is waiting for block confirmation. |
EntryFailureCodeenum
EntryFailureCode is a stable, machine-readable classification of why a FAILED WalletEntry failed. It complements the free-text failure_reason so clients can branch on failure cause without string matching.
| Name | Number | Description |
|---|---|---|
ENTRY_FAILURE_CODE_UNSPECIFIED | 0 | ENTRY_FAILURE_CODE_UNSPECIFIED is the zero value used for non-failed entries or when the cause is unknown. |
ENTRY_FAILURE_CODE_TIMED_OUT | 1 | ENTRY_FAILURE_CODE_TIMED_OUT means the operation exceeded the wallet deadline before reaching a terminal state. |
ENTRY_FAILURE_CODE_EXPIRED | 2 | ENTRY_FAILURE_CODE_EXPIRED means the swap expired before it was funded. |
ENTRY_FAILURE_CODE_REFUNDED | 3 | ENTRY_FAILURE_CODE_REFUNDED means an outbound payment was refunded back to the wallet. |
ENTRY_FAILURE_CODE_NEEDS_INTERVENTION | 4 | ENTRY_FAILURE_CODE_NEEDS_INTERVENTION means the swap reached an anomalous state requiring manual recovery. |
ENTRY_FAILURE_CODE_FAILED | 5 | ENTRY_FAILURE_CODE_FAILED is a generic terminal failure with no more specific classification. |
SubscribeGapmessage
SubscribeGap tells a subscriber the daemon could not keep it current on the live stream (a slow consumer overflowed the send buffer). The subscriber should reconcile via List and resume from the enclosing cursor. No activity is lost: the canonical event log retains every event, so the resume replays anything missed.
| Field | Type | Description |
|---|---|---|
reason | string | reason is a short human-readable description of why the gap was emitted. |