OfferSidecar
OfferSidecar is step 1/4 of the sidecar negotiation between the provider (the trader submitting the bid order) and the recipient (the trader receiving the sidecar channel). This step must be run by the provider. The result is a sidecar ticket with an offer to lease a sidecar channel for the recipient. The offer will be signed with the provider's lnd node public key. The ticket returned by this call will have the state "offered".
Source: poolrpc/trader.proto
gRPC
rpc OfferSidecar (OfferSidecarRequest) returns (SidecarTicket);
REST
HTTP Method | Path |
---|---|
POST | /v1/pool/sidecar/offer |
Code Samples
- gRPC
- REST
- Shell
- Javascript
- Python
const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const GRPC_HOST = 'localhost:12010'
const MACAROON_PATH = 'POOL_DIR/regtest/pool.macaroon'
const TLS_PATH = 'POOL_DIR/tls.cert'
const loaderOptions = {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
};
const packageDefinition = protoLoader.loadSync('poolrpc/trader.proto', loaderOptions);
const poolrpc = grpc.loadPackageDefinition(packageDefinition).poolrpc;
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
const tlsCert = fs.readFileSync(TLS_PATH);
const sslCreds = grpc.credentials.createSsl(tlsCert);
const macaroon = fs.readFileSync(MACAROON_PATH).toString('hex');
const macaroonCreds = grpc.credentials.createFromMetadataGenerator(function(args, callback) {
let metadata = new grpc.Metadata();
metadata.add('macaroon', macaroon);
callback(null, metadata);
});
let creds = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
let client = new poolrpc.Trader(GRPC_HOST, creds);
let request = {
auto_negotiate: <bool>,
bid: <Bid>,
};
client.offerSidecar(request, function(err, response) {
console.log(response);
});
// Console output:
// {
// "ticket": <string>,
// }
import codecs, grpc, os
# Generate the following 2 modules by compiling the poolrpc/trader.proto with the grpcio-tools.
# See https://github.com/lightningnetwork/lnd/blob/master/docs/grpc/python.md for instructions.
import trader_pb2 as poolrpc, trader_pb2_grpc as traderstub
GRPC_HOST = 'localhost:12010'
MACAROON_PATH = 'POOL_DIR/regtest/pool.macaroon'
TLS_PATH = 'POOL_DIR/tls.cert'
# create macaroon credentials
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
def metadata_callback(context, callback):
callback([('macaroon', macaroon)], None)
auth_creds = grpc.metadata_call_credentials(metadata_callback)
# create SSL credentials
os.environ['GRPC_SSL_CIPHER_SUITES'] = 'HIGH+ECDSA'
cert = open(TLS_PATH, 'rb').read()
ssl_creds = grpc.ssl_channel_credentials(cert)
# combine macaroon and SSL credentials
combined_creds = grpc.composite_channel_credentials(ssl_creds, auth_creds)
# make the request
channel = grpc.secure_channel(GRPC_HOST, combined_creds)
stub = traderstub.TraderStub(channel)
request = poolrpc.OfferSidecarRequest(
auto_negotiate=<bool>,
bid=<Bid>,
)
response = stub.OfferSidecar(request)
print(response)
# {
# "ticket": <string>,
# }
- Javascript
- Python
const fs = require('fs');
const request = require('request');
const REST_HOST = 'localhost:8281'
const MACAROON_PATH = 'POOL_DIR/regtest/pool.macaroon'
let requestBody = {
auto_negotiate: <boolean>, // <bool>
bid: <object>, // <Bid>
};
let options = {
url: `https://${REST_HOST}/v1/pool/sidecar/offer`,
// Work-around for self-signed certificates.
rejectUnauthorized: false,
json: true,
headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(MACAROON_PATH).toString('hex'),
},
form: JSON.stringify(requestBody),
}
request.post(options, function(error, response, body) {
console.log(body);
});
// Console output:
// {
// "ticket": <string>, // <string>
// }
import base64, codecs, json, requests
REST_HOST = 'localhost:8281'
MACAROON_PATH = 'POOL_DIR/regtest/pool.macaroon'
TLS_PATH = 'POOL_DIR/tls.cert'
url = f'https://{REST_HOST}/v1/pool/sidecar/offer'
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
headers = {'Grpc-Metadata-macaroon': macaroon}
data = {
'auto_negotiate': <bool>,
'bid': <Bid>,
}
r = requests.post(url, headers=headers, data=json.dumps(data), verify=TLS_PATH)
print(r.json())
# {
# "ticket": <string>,
# }
$ pool sidecar offer --help
NAME:
pool sidecar offer - offer a sidecar channel
USAGE:
pool sidecar offer [command options] [<full bid args> --auto] | capacity self_chan_balance lease_duration_blocks acct_key
DESCRIPTION:
Creates an offer for providing a sidecar channel to another node.
If the auto flag is specified, then all bid information needs to be
specified as normal. If the auto flag isn't specified, then only
capacity, self_chan_balance, lease_duration_blocks, and acct_key
need to set.
OPTIONS:
--interest_rate_percent value the total percent one is willing to pay or accept as yield for the specified interval (default: 0)
--amt value the amount of inbound liquidity in satoshis to request (default: 0)
--acct_key value the account key to use to pay the order fees with
--lease_duration_blocks value the number of blocks that the liquidity should be provided for (default: 2016)
--min_node_tier value the min node tier this bid should be matched with, tier 1 nodes are considered 'good', if set to tier 0, then all nodes will be considered regardless of 'quality' (default: 0)
--min_chan_amt value the minimum amount of satoshis that a resulting channel from this order must have (default: 0)
--force skip order placement confirmation
--self_chan_balance value give the channel leased by this bid order an initial balance by adding additional funds from our account into the channel; can be used to create up to 50/50 balanced channels (default: 0)
--unannounced_channel flag used to signal that this bid is interested only in unannounced channels. If this flag is not set, the channels resulting from matching this order will be announced to the network
--zero_conf_channel flag used to signal that this bid is only interested in zero conf channels
--max_batch_fee_rate value the maximum fee rate (sat/vByte) to use to for the batch transaction (default: 100)
--channel_type value the type of channel resulting from the order being matched ("legacy", "script-enforced", "simple-taproot")
--auction_type value the auction market where this offer must be considered in during matching ("inbound", "outbound") (default: "inbound")
--allowed_node_id value the list of nodes this order is allowed to match with; if empty, the order will be able to match with any node unless not_allowed_node_id is set. Can be specified multiple times
--not_allowed_node_id value the list of nodes this order is not allowed to match with; if empty, the order will be able to match with any node unless allowed_node_id is set. Can be specified multiple times
--public flag used to signal that this order's details can be shared in public market places.
--auto if true, then the full bid information needs to be specified as automated negotiation will be attempted
Messages
poolrpc.OfferSidecarRequest
Source: poolrpc/trader.proto
Field | gRPC Type | REST Type | REST Placement |
---|---|---|---|
auto_negotiate | bool | boolean | body |
bid | Bid | object | body |
poolrpc.SidecarTicket
Source: poolrpc/trader.proto
Field | gRPC Type | REST Type |
---|---|---|
ticket | string | string |
Nested Messages
poolrpc.Bid
Field | gRPC Type | REST Type |
---|---|---|
details | Order | object |
lease_duration_blocks | uint32 | integer |
version | uint32 | integer |
min_node_tier | NodeTier | string |
self_chan_balance | uint64 | string |
sidecar_ticket | string | string |
unannounced_channel | bool | boolean |
zero_conf_channel | bool | boolean |
poolrpc.MatchEvent
Field | gRPC Type | REST Type |
---|---|---|
match_state | MatchState | string |
units_filled | uint32 | integer |
matched_order | bytes | string |
reject_reason | MatchRejectReason | string |
poolrpc.Order
Field | gRPC Type | REST Type |
---|---|---|
trader_key | bytes | string |
rate_fixed | uint32 | integer |
amt | uint64 | string |
max_batch_fee_rate_sat_per_kw | uint64 | string |
order_nonce | bytes | string |
state | OrderState | string |
units | uint32 | integer |
units_unfulfilled | uint32 | integer |
reserved_value_sat | uint64 | string |
creation_timestamp_ns | uint64 | string |
events | OrderEvent[] | array |
min_units_match | uint32 | integer |
channel_type | OrderChannelType | string |
allowed_node_ids | bytes[] | array |
not_allowed_node_ids | bytes[] | array |
auction_type | AuctionType | string |
is_public | bool | boolean |
poolrpc.OrderEvent
Field | gRPC Type | REST Type |
---|---|---|
timestamp_ns | int64 | string |
event_str | string | string |
state_change | UpdatedEvent | object |
matched | MatchEvent | object |
poolrpc.UpdatedEvent
Field | gRPC Type | REST Type |
---|---|---|
previous_state | OrderState | string |
new_state | OrderState | string |
units_filled | uint32 | integer |
Enums
poolrpc.AuctionType
Name | Number |
---|---|
AUCTION_TYPE_BTC_INBOUND_LIQUIDITY | 0 |
AUCTION_TYPE_BTC_OUTBOUND_LIQUIDITY | 1 |
poolrpc.MatchRejectReason
Name | Number |
---|---|
NONE | 0 |
SERVER_MISBEHAVIOR | 1 |
BATCH_VERSION_MISMATCH | 2 |
PARTIAL_REJECT_COLLATERAL | 3 |
PARTIAL_REJECT_DUPLICATE_PEER | 4 |
PARTIAL_REJECT_CHANNEL_FUNDING_FAILED | 5 |
poolrpc.MatchState
Name | Number |
---|---|
PREPARE | 0 |
ACCEPTED | 1 |
REJECTED | 2 |
SIGNED | 3 |
FINALIZED | 4 |
poolrpc.NodeTier
Name | Number |
---|---|
TIER_DEFAULT | 0 |
TIER_0 | 1 |
TIER_1 | 2 |
poolrpc.OrderChannelType
Name | Number |
---|---|
ORDER_CHANNEL_TYPE_UNKNOWN | 0 |
ORDER_CHANNEL_TYPE_PEER_DEPENDENT | 1 |
ORDER_CHANNEL_TYPE_SCRIPT_ENFORCED | 2 |
ORDER_CHANNEL_TYPE_SIMPLE_TAPROOT | 3 |
poolrpc.OrderState
Name | Number |
---|---|
ORDER_SUBMITTED | 0 |
ORDER_CLEARED | 1 |
ORDER_PARTIALLY_FILLED | 2 |
ORDER_EXECUTED | 3 |
ORDER_CANCELED | 4 |
ORDER_EXPIRED | 5 |
ORDER_FAILED | 6 |