BakeMacaroon
BakeMacaroon allows the creation of a new macaroon with custom permissions. No first-party caveats are added since this can be done offline.
Source: taprootassets.proto
gRPC
rpc BakeMacaroon (BakeMacaroonRequest) returns (BakeMacaroonResponse);
REST
| HTTP Method | Path |
|---|---|
| POST | /v1/taproot-assets/macaroon |
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:10029'
const MACAROON_PATH = 'TAPROOT-ASSETS_DIR/regtest/taproot-assets.macaroon'
const TLS_PATH = 'TAPROOT-ASSETS_DIR/tls.cert'
const loaderOptions = {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
};
const packageDefinition = protoLoader.loadSync('taprootassets.proto', loaderOptions);
const taprpc = grpc.loadPackageDefinition(packageDefinition).taprpc;
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 taprpc.TaprootAssets(GRPC_HOST, creds);
let request = {
permissions: <MacaroonPermission>,
root_key_id: <uint64>,
allow_external_permissions: <bool>,
};
client.bakeMacaroon(request, function(err, response) {
console.log(response);
});
// Console output:
// {
// "macaroon": <string>,
// }
import codecs, grpc, os
# Generate the following 2 modules by compiling the taprootassets.proto with the grpcio-tools.
# See https://github.com/lightningnetwork/lnd/blob/master/docs/grpc/python.md for instructions.
import taprootassets_pb2 as taprpc, taprootassets_pb2_grpc as taprootassetsstub
GRPC_HOST = 'localhost:10029'
MACAROON_PATH = 'TAPROOT-ASSETS_DIR/regtest/taproot-assets.macaroon'
TLS_PATH = 'TAPROOT-ASSETS_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 = taprootassetsstub.TaprootAssetsStub(channel)
request = taprpc.BakeMacaroonRequest(
permissions=<MacaroonPermission>,
root_key_id=<uint64>,
allow_external_permissions=<bool>,
)
response = stub.BakeMacaroon(request)
print(response)
# {
# "macaroon": <string>,
# }
- Javascript
- Python
const fs = require('fs');
const request = require('request');
const REST_HOST = 'localhost:8089'
const MACAROON_PATH = 'TAPROOT-ASSETS_DIR/regtest/taproot-assets.macaroon'
let requestBody = {
permissions: <array>, // <MacaroonPermission>
root_key_id: <string>, // <uint64>
allow_external_permissions: <boolean>, // <bool>
};
let options = {
url: `https://${REST_HOST}/v1/taproot-assets/macaroon`,
// 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:
// {
// "macaroon": <string>, // <string>
// }
import base64, codecs, json, requests
REST_HOST = 'localhost:8089'
MACAROON_PATH = 'TAPROOT-ASSETS_DIR/regtest/taproot-assets.macaroon'
TLS_PATH = 'TAPROOT-ASSETS_DIR/tls.cert'
url = f'https://{REST_HOST}/v1/taproot-assets/macaroon'
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
headers = {'Grpc-Metadata-macaroon': macaroon}
data = {
'permissions': <MacaroonPermission>,
'root_key_id': <uint64>,
'allow_external_permissions': <bool>,
}
r = requests.post(url, headers=headers, data=json.dumps(data), verify=TLS_PATH)
print(r.json())
# {
# "macaroon": <string>,
# }
$ tapcli bakemacaroon --help
NAME:
tapcli bakemacaroon - Bakes a new macaroon with the provided list of permissions and restrictions.
USAGE:
tapcli bakemacaroon [command options] [--save_to=] [--timeout=] [--ip_address=] [--custom_caveat_name= [--custom_caveat_condition=]] [--root_key_id=] [--allow_external_permissions] [--root_key=] permissions...
CATEGORY:
Macaroons
DESCRIPTION:
Bake a new macaroon that grants the provided permissions and
optionally adds restrictions (timeout, IP address) to it.
The new macaroon can either be shown on command line in hex serialized
format or it can be saved directly to a file using the --save_to
argument.
A permission is a tuple of an entity and an action, separated by a
colon. Multiple operations can be added as arguments, for example:
tapcli bakemacaroon daemon:read assets:write
For even more fine-grained permission control, it is also possible to
specify single RPC method URIs that are allowed to be accessed by a
macaroon. This can be achieved by specifying "uri:<methodURI>" pairs,
for example:
tapcli bakemacaroon uri:/taprpc.TaprootAssets/GetInfo uri:/universerpc.Universe/Info
If the root key is known, it can be passed directly as a hex encoded
string using the --root_key flag. This turns the command into an
offline operation and the macaroon will be created without calling
into the server's RPC endpoint.
OPTIONS:
--save_to value save the created macaroon to this file using the default binary format
--timeout value the number of seconds the macaroon will be valid before it times out (default: 0)
--ip_address value the IP address the macaroon will be bound to
--ip_range value the IP range the macaroon will be bound to
--custom_caveat_name value the name of the custom caveat to add
--custom_caveat_condition value the condition of the custom caveat to add, can be empty if custom caveat doesn't need a value
--root_key_id value the numerical root key ID used to create the macaroon (default: 0)
--allow_external_permissions whether permissions tapd is not familiar with are allowed
--root_key value if the root key is known, it can be passed directly as a hex encoded string, turning the command into an offline operation
Messages
taprpc.BakeMacaroonRequest
Source: taprootassets.proto
| Field | gRPC Type | REST Type | REST Placement |
|---|---|---|---|
permissions | MacaroonPermission[] | array | body |
root_key_id | uint64 | string | body |
allow_external_permissions | bool | boolean | body |
taprpc.BakeMacaroonResponse
Source: taprootassets.proto
| Field | gRPC Type | REST Type |
|---|---|---|
macaroon | string | string |
Nested Messages
taprpc.MacaroonPermission
| Field | gRPC Type | REST Type |
|---|---|---|
entity | string | string |
action | string | string |