def new_address(container): channel = get_channel(container) macaroon = codecs.encode(open(_macaroon(container), 'rb').read(), 'hex') stub = lnrpc.LightningStub(channel) request = ln.NewAddressRequest(type=0) response = stub.NewAddress(request, metadata=[('macaroon', macaroon)]) return response.address
class GetBTCAddress(AbstractMethod, LoggerMixin): """method to get btc address""" async def run(self, user): """ return bitcoin address of user. If the address does not exist asynchronously generate a new lightning address gRPC Response: NewAddressResponse see https://api.lightning.community/#newaddress for more info """ # return address if it exists if address := user.bitcoin_address: return address # create a new address request = ln.NewAddressRequest(type=0) response = await LND.stub.NewAddress(request) address = response.address.upper() await user.update(bitcoin_address=address).apply() self.logger.warning("Created address: %s for user: %s", address, user.username) await BITCOIND.req( "importaddress", params={ "address": address, "label": user.username, "rescan": False }, ) return address
def addfunds(self, bitcoind, satoshis): req = lnrpc.NewAddressRequest(type=1) addr = self.rpc.stub.NewAddress(req).address txid = bitcoind.rpc.sendtoaddress(addr, float(satoshis) / 10**8) self.daemon.wait_for_log("Inserting unconfirmed transaction") bitcoind.rpc.generate(1) self.daemon.wait_for_log("Marking unconfirmed transaction") # The above still doesn't mean the wallet balance is updated, # so let it settle a bit time.sleep(1) assert(self.rpc.stub.WalletBalance(lnrpc.WalletBalanceRequest()).balance == satoshis)
def main(): # sets up grpc connection to lnd channel = get_secure_channel() # note that the 'admin' macaroon already has the required # permissions for the walletkit request, so we don't need # that third macaroon. macaroon, signer_macaroon = get_macaroons(["admin", "signer"]) # the main stub allows access to the default rpc commands: stub = lnrpc.LightningStub(channel) # the signer stub allows us to access the rpc for signing # transactions on our coins: stub_signer = signrpc.SignerStub(channel) # we also need a stub for the walletkit rpc to extract # public keys for addresses holding coins: stub_walletkit = walletrpc.WalletKitStub(channel) # Here we start the process to sign a custom tx. # 1. List unspent coins, get most recent ones (just an example). # 2. Get the pubkeys of those addresses. # 3. Get the next unused address in the wallet as destination. # 4. Build a transaction, (in future: optionally taking extra # inputs and outputs from elsewhere). # 5. Use signOutputRaw rpc to sign the new transaction. # 6. Use the walletkit PublishTransaction to publish. # Just an example of retrieving basic info, not necessary: # Retrieve and display the wallet balance response = stub.WalletBalance(ln.WalletBalanceRequest(), metadata=[('macaroon', macaroon)]) print("Current on-chain wallet balance: ", response.total_balance) inputs = get_our_coins(stub, macaroon) + get_other_coins() for inp in inputs: # Attach auxiliary data needed to the inputs, for signing. # Get the public key of an address inp["pubkey"] = stub_walletkit.KeyForAddress( walletkit.KeyForAddressRequest(addr_in=inp["utxo"].address), metadata=[('macaroon', macaroon)]).raw_key_bytes # this data (known as scriptCode in BIP143 parlance) # is the pubkeyhash script for this p2wpkh, as is needed # to construct the signature hash. # **NOTE** This code currently works with bech32 only. # TODO update to allow p2sh-p2wpkh in wallet coins, also. inp["script"] = btc.pubkey_to_p2pkh_script(inp["pubkey"]) # We need an output address for the transaction, this is taken from the # standard wallet 'new address' request (type 0 is bech32 p2wpkh): request = ln.NewAddressRequest(type=0, ) response = stub.NewAddress(request, metadata=[('macaroon', macaroon)]) output_address = response.address print("Generated new address: ", output_address) # Build the raw unsigned transaction tx_ins = [] output_amt = 0 for inp in inputs: tx_ins.append(inp["utxo"].outpoint.txid_str + ":" + str(inp["utxo"].outpoint.output_index)) output_amt += inp["utxo"].amount_sat fee_est = estimate_tx_fee(2, 1, "p2wpkh", 6, stub, macaroon) output = {"address": output_address, "value": output_amt - fee_est} tx_unsigned = btc.mktx(tx_ins, [output], version=2) print(btc.deserialize(tx_unsigned)) # use SignOutputRaw to sign each input (currently, they are all ours). raw_sigs = {} for i, inp in enumerate(inputs): # KeyDescriptors must contain at least one of the pubkey and the HD path, # here we use the latter: kd = signer.KeyDescriptor(raw_key_bytes=inp["pubkey"]) # specify the utxo information for this input into a TxOut: sdout = signer.TxOut(value=inp["utxo"].amount_sat, pk_script=unhexlify(inp["utxo"].pk_script)) # we must pass a list of SignDescriptors; we could batch all into # one grpc call if we preferred. The witnessscript field is # constructed above as the "script" field in the input dict. sds = [ signer.SignDescriptor(key_desc=kd, input_index=i, output=sdout, witness_script=inp["script"], sighash=1) ] req = signer.SignReq(raw_tx_bytes=unhexlify(tx_unsigned), sign_descs=sds) # here we make the actual signing request to lnd over grpc: response = stub_signer.SignOutputRaw(req, metadata=[('macaroon', signer_macaroon)]) # note that btcwallet's sign function does not return the sighash byte, # it must be added manually: raw_sigs[i] = response.raw_sigs[0] + sighash_all_bytes # insert the signatures into the relevant inputs in the deserialized tx tx_unsigned_deser = btc.deserialize(tx_unsigned) for i in range(len(inputs)): tx_unsigned_deser["ins"][i]["txinwitness"] = [ btc.safe_hexlify(raw_sigs[i]), btc.safe_hexlify(inputs[i]["pubkey"]) ] print("Signed transaction: \n", tx_unsigned_deser) hextx = btc.serialize(tx_unsigned_deser) print("Serialized: ", hextx) print("You can broadcast this externally e.g. via Bitcoin Core")
def address(self): try: response = self.client.NewAddress(ln.NewAddressRequest()) return response except Exception as e: logger.exception(e)
aezeed_passphrase=None) response = stub.InitWallet(request) print(response) time.sleep(10) time.sleep(10) for i in range(n): os.chdir("/Users/thanh_nc/lnd/simnet/" + str(i)) print(directory + str(i) + '/lnd/tls.cert') cert = open(directory + str(i) + '/lnd/tls.cert').read() creds = grpc.ssl_channel_credentials(cert) port = str(i) if i >= 10 else '0' + str(i) channel = grpc.secure_channel('localhost:100' + port, creds) stub = lnrpc.LightningStub(channel) request = ln.NewAddressRequest(type=1) response = stub.NewAddress(request) print response btcd.terminate() command_line = "/Users/thanh_nc/go/bin/btcd --txindex --simnet --maxpeers=100 --rpcmaxwebsockets=100 --rpcuser=kek --rpcpass=kek --miningaddr=" + response.address print command_line args = shlex.split(command_line) btcd = Popen(args) time.sleep(10) command_line = "/Users/thanh_nc/go/bin/btcctl --simnet --rpcuser=kek --rpcpass=kek generate 200" print command_line args = shlex.split(command_line) call(args) time.sleep(10) time.sleep(5)