diff --git a/proto/cusf/mainchain/v1/wallet.proto b/proto/cusf/mainchain/v1/wallet.proto index ac00771..566a5bb 100644 --- a/proto/cusf/mainchain/v1/wallet.proto +++ b/proto/cusf/mainchain/v1/wallet.proto @@ -65,6 +65,34 @@ service WalletService { } // Available on regtest and signet only. rpc GenerateBlocks(GenerateBlocksRequest) returns (stream GenerateBlocksResponse); + + rpc GetBip47PaymentCode(GetBip47PaymentCodeRequest) returns (GetBip47PaymentCodeResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + rpc SendToBip47PaymentCode(SendToBip47PaymentCodeRequest) returns (SendToBip47PaymentCodeResponse); + rpc ListBip47InboundPayers(ListBip47InboundPayersRequest) returns (ListBip47InboundPayersResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + rpc GetSilentPaymentAddress(GetSilentPaymentAddressRequest) returns (GetSilentPaymentAddressResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // Also rescans from the wallet birthday, so that past payments to the + // new label surface. + rpc CreateSilentPaymentLabel(CreateSilentPaymentLabelRequest) returns (CreateSilentPaymentLabelResponse); + rpc ListSilentPaymentLabels(ListSilentPaymentLabelsRequest) returns (ListSilentPaymentLabelsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + rpc SendToSilentPayment(SendToSilentPaymentRequest) returns (SendToSilentPaymentResponse); + rpc ListSilentPaymentReceives(ListSilentPaymentReceivesRequest) returns (ListSilentPaymentReceivesResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + rpc GetReusableScanStatus(GetReusableScanStatusRequest) returns (GetReusableScanStatusResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // Returns immediately; observe progress via GetReusableScanStatus. + rpc RescanReusablePayments(RescanReusablePaymentsRequest) returns (RescanReusablePaymentsResponse) { + option idempotency_level = IDEMPOTENT; + } } message BroadcastWithdrawalBundleRequest { @@ -283,3 +311,140 @@ message ListUnspentOutputsResponse { repeated Output outputs = 1; } + +enum Bip47Version { + BIP47_VERSION_UNSPECIFIED = 0; + BIP47_VERSION_V1 = 1; + BIP47_VERSION_V3 = 3; +} + +message Bip47InboundPayer { + string payment_code = 1; + Bip47Version version = 2; + uint32 next_receive_index = 3; + uint64 total_received_sats = 4; + + // When we first observed the notification tx. + google.protobuf.Timestamp first_seen = 5; +} + +message SilentPaymentLabel { + // Label index. m=0 is reserved for change. + uint32 m = 1; + + string name = 2; + string address = 3; +} + +message SilentPaymentReceive { + cusf.common.v1.ReverseHex txid = 1; + uint32 vout = 2; + + // X-only taproot output pubkey, 32 bytes. + bytes output_pubkey = 3; + + uint64 amount_sats = 4; + uint32 tweak_k = 5; + + // Set when the output was paid to a labeled address. Absent = + // base address; 0 = change; >=1 = user label. + optional uint32 label_m = 6; + optional string label_name = 7; + + uint32 height = 8; + + // Set if we have observed an on-chain spend of this UTXO. + optional cusf.common.v1.ReverseHex spent_in_txid = 9; +} + +message GetBip47PaymentCodeRequest { + Bip47Version version = 1; +} +message GetBip47PaymentCodeResponse { + string payment_code = 1; + + // P2PKH address that notification txs to us pay to. + string notification_address = 2; + + Bip47Version version = 3; +} + +message SendToBip47PaymentCodeRequest { + string payment_code = 1; + uint64 amount_sats = 2; + uint64 fee_sat_per_vbyte = 3; +} +message SendToBip47PaymentCodeResponse { + // Set on the first send to a given recipient; unset on subsequent sends + // (per BIP47, notification happens only on first interaction). + optional cusf.common.v1.ReverseHex notification_txid = 1; + + cusf.common.v1.ReverseHex payment_txid = 2; + uint32 sender_index = 3; + Bip47Version version = 4; +} + +message ListBip47InboundPayersRequest {} +message ListBip47InboundPayersResponse { + repeated Bip47InboundPayer payers = 1; +} + +message GetSilentPaymentAddressRequest { + // If set, return the labeled address instead of the base address. + optional uint32 label = 1; +} +message GetSilentPaymentAddressResponse { + string address = 1; +} + +message CreateSilentPaymentLabelRequest { + string name = 1; +} +message CreateSilentPaymentLabelResponse { + uint32 label_m = 1; + string labeled_address = 2; +} + +message ListSilentPaymentLabelsRequest {} +message ListSilentPaymentLabelsResponse { + repeated SilentPaymentLabel labels = 1; +} + +message SendToSilentPaymentRequest { + message Recipient { + string sp_address = 1; + uint64 amount_sats = 2; + } + repeated Recipient recipients = 1; + uint64 fee_sat_per_vbyte = 2; +} +message SendToSilentPaymentResponse { + cusf.common.v1.ReverseHex txid = 1; +} + +message ListSilentPaymentReceivesRequest { + optional uint32 min_confirmations = 1; + + // If not set, the server may apply a default ceiling. + optional uint32 limit = 2; +} +message ListSilentPaymentReceivesResponse { + repeated SilentPaymentReceive items = 1; + uint32 scan_tip_height = 2; +} + +message GetReusableScanStatusRequest {} +message GetReusableScanStatusResponse { + uint32 tip_height = 1; + uint32 last_scanned_height = 2; + uint32 birthday_height = 3; + bool catching_up = 4; +} + +message RescanReusablePaymentsRequest { + // All matches at or above this height are dropped before rescanning. + uint32 from_height = 1; +} +message RescanReusablePaymentsResponse { + uint32 scheduled_from_height = 1; +}