// SettleHodlInvoice sets the preimage of a hodl invoice.
172886
func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
	i.Lock()
	defer i.Unlock()

	invoice, err := i.cdb.SettleHoldInvoice(preimage)
	if err != nil {
		log.Errorf("SettleHodlInvoice with preimage %v: %v", preimage, err)
		return err
	}

	hash := preimage.Hash()
	log.Debugf("Invoice(%v): settled with preimage %v", hash,
		invoice.Terms.PaymentPreimage)

	i.notifyHodlSubscribers(HodlEvent{
		Hash:     hash,
		Preimage: &preimage,
	})
	i.notifyClients(hash, invoice, invoice.Terms.State)

	return nil
}
202857
func (client *Client) GetInvoice(invId string) (inv invoice, err error) {
	url := client.ApiUri + "/invoices/" + invId
	htclient := setHttpClient(client)
	response, _ := htclient.Get(url)
	inv, err = processInvoice(response)
	return inv, err
}
885410
func (r Billing_Invoice) EmailInvoices(options *datatypes.Container_Billing_Invoice_Email) (err error) {
	var resp datatypes.Void
	params := []interface{}{
		options,
	}
	err = r.Session.DoRequest("SoftLayer_Billing_Invoice", "emailInvoices", params, &r.Options, &resp)
	return
}
937536
func (t *Tracker) resolveClaim(ticketCh chan bool) error {
	logger.Tracef("resolving %s leadership ticket for %s...", t.applicationName, t.unitName)
	defer close(ticketCh)
	if leader, err := t.isLeader(); err != nil {
		return errors.Trace(err)
	} else if !leader {
		logger.Debugf("%s is not %s leader", t.unitName, t.applicationName)
		return nil
	}
	logger.Tracef("confirming %s leadership for %s", t.applicationName, t.unitName)
	return t.sendTrue(ticketCh)
}
52593
func HtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
	sweepTx *wire.MsgTx, csvDelay uint32) (wire.TxWitness, error) {

	// We're required to wait a relative period of time before we can sweep
	// the output in order to allow the other party to contest our claim of
	// validity to this version of the commitment transaction.
	sweepTx.TxIn[0].Sequence = LockTimeToSequence(false, csvDelay)

	// Finally, OP_CSV requires that the version of the transaction
	// spending a pkscript with OP_CSV within it *must* be >= 2.
	sweepTx.Version = 2

	// As we mutated the transaction, we'll re-calculate the sighashes for
	// this instance.
	signDesc.SigHashes = txscript.NewTxSigHashes(sweepTx)

	// With the proper sequence and version set, we'll now sign the timeout
	// transaction using the passed signed descriptor. In order to generate
	// a valid signature, then signDesc should be using the base delay
	// public key, and the proper single tweak bytes.
	sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
	if err != nil {
		return nil, err
	}

	// We set a zero as the first element the witness stack (ignoring the
	// witness script), in order to force execution to the second portion
	// of the if clause.
	witnessStack := wire.TxWitness(make([][]byte, 3))
	witnessStack[0] = append(sweepSig, byte(signDesc.HashType))
	witnessStack[1] = nil
	witnessStack[2] = signDesc.WitnessScript

	return witnessStack, nil
}
924430
func claimPaymentWithDetail(mctx libkb.MetaContext, walletState *WalletState,
	p stellar1.PaymentSummaryRelay, into stellar1.AccountID, dir *stellar1.RelayDirection) (res stellar1.RelayClaimResult, err error) {
	if p.Claim != nil && p.Claim.TxStatus == stellar1.TransactionStatus_SUCCESS {
		recipient, _, err := mctx.G().GetUPAKLoader().Load(libkb.NewLoadUserByUIDArg(mctx.Ctx(), mctx.G(), p.Claim.To.Uid))
		if err != nil || recipient == nil {
			return res, fmt.Errorf("Payment already claimed")
		}
		return res, fmt.Errorf("Payment already claimed by %v", recipient.GetName())
	}
	rsec, err := relays.DecryptB64(mctx, p.TeamID, p.BoxB64)
	if err != nil {
		return res, fmt.Errorf("error opening secret to claim: %v", err)
	}
	skey, _, _, err := libkb.ParseStellarSecretKey(rsec.Sk.SecureNoLogString())
	if err != nil {
		return res, fmt.Errorf("error using shared secret key: %v", err)
	}
	destinationFunded, err := isAccountFunded(mctx.Ctx(), walletState, into)
	if err != nil {
		return res, err
	}
	useDir := stellar1.RelayDirection_CLAIM
	if dir == nil {
		// Infer direction
		if p.From.Uid.Equal(mctx.ActiveDevice().UID()) {
			useDir = stellar1.RelayDirection_YANK
		}
	} else {
		// Direction from caller
		useDir = *dir
	}

	baseFee := walletState.BaseFee(mctx)
	sp, unlock := NewClaimSeqnoProvider(mctx, walletState)
	defer unlock()
	tb, err := getTimeboundsForSending(mctx, walletState)
	if err != nil {
		return res, err
	}
	sig, err := stellarnet.RelocateTransaction(stellarnet.SeedStr(skey.SecureNoLogString()),
		stellarnet.AddressStr(into.String()), destinationFunded, nil, sp, tb, baseFee)
	if err != nil {
		return res, fmt.Errorf("error building claim transaction: %v", err)
	}
	return walletState.SubmitRelayClaim(mctx.Ctx(), stellar1.RelayClaimPost{
		KeybaseID:         p.KbTxID,
		Dir:               useDir,
		SignedTransaction: sig.Signed,
	})
}
1345952
func ComposeVersionNegotiation(destConnID, srcConnID protocol.ConnectionID, versions []protocol.VersionNumber) ([]byte, error) {
	greasedVersions := protocol.GetGreasedVersions(versions)
	expectedLen := 1 /* type byte */ + 4 /* version field */ + 1 /* connection ID length field */ + destConnID.Len() + srcConnID.Len() + len(greasedVersions)*4
	buf := bytes.NewBuffer(make([]byte, 0, expectedLen))
	r := make([]byte, 1)
	_, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here.
	buf.WriteByte(r[0] | 0xc0)
	utils.BigEndian.WriteUint32(buf, 0) // version 0
	connIDLen, err := encodeConnIDLen(destConnID, srcConnID)
	if err != nil {
		return nil, err
	}
	buf.WriteByte(connIDLen)
	buf.Write(destConnID)
	buf.Write(srcConnID)
	for _, v := range greasedVersions {
		utils.BigEndian.WriteUint32(buf, uint32(v))
	}
	return buf.Bytes(), nil
}
516761
func (s *Service) InvoiceInfo(ctx context.Context, invoiceIdentity int) (*Invoice, error) {
	var invoice Invoice
	return &invoice, s.Get(ctx, &invoice, fmt.Sprintf("/account/invoices/%v", invoiceIdentity), nil, nil)
}
915555
func (d *DB) CancelInvoice(paymentHash lntypes.Hash) (*Invoice, error) {
	var canceledInvoice *Invoice
	err := d.Update(func(tx *bbolt.Tx) error {
		invoices, err := tx.CreateBucketIfNotExists(invoiceBucket)
		if err != nil {
			return err
		}
		invoiceIndex, err := invoices.CreateBucketIfNotExists(
			invoiceIndexBucket,
		)
		if err != nil {
			return err
		}

		// Check the invoice index to see if an invoice paying to this
		// hash exists within the DB.
		invoiceNum := invoiceIndex.Get(paymentHash[:])
		if invoiceNum == nil {
			return ErrInvoiceNotFound
		}

		canceledInvoice, err = cancelInvoice(invoices, invoiceNum)

		return err
	})

	return canceledInvoice, err
}
837357
func (h *htlcTimeoutResolver) claimCleanUp(
	commitSpend *chainntnfs.SpendDetail) (ContractResolver, error) {

	// Depending on if this is our commitment or not, then we'll be looking
	// for a different witness pattern.
	spenderIndex := commitSpend.SpenderInputIndex
	spendingInput := commitSpend.SpendingTx.TxIn[spenderIndex]

	log.Infof("%T(%v): extracting preimage! remote party spent "+
		"HTLC with tx=%v", h, h.htlcResolution.ClaimOutpoint,
		spew.Sdump(commitSpend.SpendingTx))

	// If this is the remote party's commitment, then we'll be looking for
	// them to spend using the second-level success transaction.
	var preimageBytes []byte
	if h.htlcResolution.SignedTimeoutTx == nil {
		// The witness stack when the remote party sweeps the output to
		// them looks like:
		//
		//  * <0> <sender sig> <recvr sig> <preimage> <witness script>
		preimageBytes = spendingInput.Witness[remotePreimageIndex]
	} else {
		// Otherwise, they'll be spending directly from our commitment
		// output. In which case the witness stack looks like:
		//
		//  * <sig> <preimage> <witness script>
		preimageBytes = spendingInput.Witness[localPreimageIndex]
	}

	preimage, err := lntypes.MakePreimage(preimageBytes)
	if err != nil {
		return nil, fmt.Errorf("unable to create pre-image from "+
			"witness: %v", err)
	}

	log.Infof("%T(%v): extracting preimage=%v from on-chain "+
		"spend!", h, h.htlcResolution.ClaimOutpoint, preimage)

	// With the preimage obtained, we can now add it to the global cache.
	if err := h.PreimageDB.AddPreimages(preimage); err != nil {
		log.Errorf("%T(%v): unable to add witness to cache",
			h, h.htlcResolution.ClaimOutpoint)
	}

	var pre [32]byte
	copy(pre[:], preimage[:])

	// Finally, we'll send the clean up message, mark ourselves as
	// resolved, then exit.
	if err := h.DeliverResolutionMsg(ResolutionMsg{
		SourceChan: h.ShortChanID,
		HtlcIndex:  h.htlcIndex,
		PreImage:   &pre,
	}); err != nil {
		return nil, err
	}
	h.resolved = true
	return nil, h.Checkpoint(h)
}
489875
func (r Account) GetPendingInvoiceTotalAmount() (resp datatypes.Float64, err error) {
	err = r.Session.DoRequest("SoftLayer_Account", "getPendingInvoiceTotalAmount", nil, &r.Options, &resp)
	return
}
868661
func newShareClaim(cl *client.Client, target blob.Ref) (blob.Ref, error) {
	var claim blob.Ref
	signer, err := cl.ServerPublicKeyBlobRef()
	if err != nil {
		return claim, fmt.Errorf("could not get signer: %v", err)
	}
	shareSchema := schema.NewShareRef(schema.ShareHaveRef, true)
	shareSchema.SetShareTarget(target)
	unsignedClaim, err := shareSchema.SetSigner(signer).JSON()
	if err != nil {
		return claim, fmt.Errorf("could not create unsigned share claim: %v", err)
	}
	signedClaim, err := cl.Sign(context.TODO(), "", strings.NewReader("json="+unsignedClaim))
	if err != nil {
		return claim, fmt.Errorf("could not get signed share claim: %v", err)
	}
	sbr, err := cl.Upload(context.TODO(), client.NewUploadHandleFromString(string(signedClaim)))
	if err != nil {
		return claim, fmt.Errorf("could not upload share claim: %v", err)
	}
	return sbr.BlobRef, nil
}
452191
func (i *InvoiceRegistry) dispatchToClients(event *invoiceEvent) {
	invoice := event.invoice

	for clientID, client := range i.notificationClients {
		// Before we dispatch this event, we'll check
		// to ensure that this client hasn't already
		// received this notification in order to
		// ensure we don't duplicate any events.

		// TODO(joostjager): Refactor switches.
		switch {
		// If we've already sent this settle event to
		// the client, then we can skip this.
		case event.state == channeldb.ContractSettled &&
			client.settleIndex >= invoice.SettleIndex:
			continue

		// Similarly, if we've already sent this add to
		// the client then we can skip this one.
		case event.state == channeldb.ContractOpen &&
			client.addIndex >= invoice.AddIndex:
			continue

		// These two states should never happen, but we
		// log them just in case so we can detect this
		// instance.
		case event.state == channeldb.ContractOpen &&
			client.addIndex+1 != invoice.AddIndex:
			log.Warnf("client=%v for invoice "+
				"notifications missed an update, "+
				"add_index=%v, new add event index=%v",
				clientID, client.addIndex,
				invoice.AddIndex)

		case event.state == channeldb.ContractSettled &&
			client.settleIndex+1 != invoice.SettleIndex:
			log.Warnf("client=%v for invoice "+
				"notifications missed an update, "+
				"settle_index=%v, new settle event index=%v",
				clientID, client.settleIndex,
				invoice.SettleIndex)
		}

		select {
		case client.ntfnQueue.ChanIn() <- &invoiceEvent{
			state:   event.state,
			invoice: invoice,
		}:
		case <-i.quit:
			return
		}

		// Each time we send a notification to a client, we'll record
		// the latest add/settle index it has. We'll use this to ensure
		// we don't send a notification twice, which can happen if a new
		// event is added while we're catching up a new client.
		switch event.state {
		case channeldb.ContractSettled:
			client.settleIndex = invoice.SettleIndex
		case channeldb.ContractOpen:
			client.addIndex = invoice.AddIndex
		default:
			log.Errorf("unexpected invoice state: %v", event.state)
		}
	}
}
440868
func (r Product_Order) GetExternalPaymentAuthorizationReceipt(token *string, payerId *string) (resp datatypes.Container_Product_Order_Receipt, err error) {
	params := []interface{}{
		token,
		payerId,
	}
	err = r.Session.DoRequest("SoftLayer_Product_Order", "getExternalPaymentAuthorizationReceipt", params, &r.Options, &resp)
	return
}
590881
func (st *State) precheckInstance(
	series string,
	cons constraints.Value,
	placement string,
	volumeAttachments []storage.VolumeAttachmentParams,
) error {
	if st.policy == nil {
		return nil
	}
	prechecker, err := st.policy.Prechecker()
	if errors.IsNotImplemented(err) {
		return nil
	} else if err != nil {
		return err
	}
	if prechecker == nil {
		return errors.New("policy returned nil prechecker without an error")
	}
	return prechecker.PrecheckInstance(
		CallContext(st),
		environs.PrecheckInstanceParams{
			Series:            series,
			Constraints:       cons,
			Placement:         placement,
			VolumeAttachments: volumeAttachments,
		})
}
311845
func (p *preimageBeacon) LookupPreimage(
	payHash lntypes.Hash) (lntypes.Preimage, bool) {

	p.RLock()
	defer p.RUnlock()

	// First, we'll check the invoice registry to see if we already know of
	// the preimage as it's on that we created ourselves.
	invoice, _, err := p.invoices.LookupInvoice(payHash)
	switch {
	case err == channeldb.ErrInvoiceNotFound:
		// If we get this error, then it simply means that this invoice
		// wasn't found, so we don't treat it as a critical error.
	case err != nil:
		return lntypes.Preimage{}, false
	}

	// If we've found the invoice, then we can return the preimage
	// directly.
	if err != channeldb.ErrInvoiceNotFound &&
		invoice.Terms.PaymentPreimage != channeldb.UnknownPreimage {

		return invoice.Terms.PaymentPreimage, true
	}

	// Otherwise, we'll perform a final check using the witness cache.
	preimage, err := p.wCache.LookupSha256Witness(payHash)
	if err != nil {
		ltndLog.Errorf("Unable to lookup witness: %v", err)
		return lntypes.Preimage{}, false
	}

	return preimage, true
}
802256
func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
	invoice *AddInvoiceData) (*lntypes.Hash, *channeldb.Invoice, error) {

	var (
		paymentPreimage lntypes.Preimage
		paymentHash     lntypes.Hash
	)

	switch {

	// Only either preimage or hash can be set.
	case invoice.Preimage != nil && invoice.Hash != nil:
		return nil, nil,
			errors.New("preimage and hash both set")

	// Prevent the unknown preimage magic value from being used for a
	// regular invoice. This would cause the invoice the be handled as if it
	// was a hold invoice.
	case invoice.Preimage != nil &&
		*invoice.Preimage == channeldb.UnknownPreimage:

		return nil, nil,
			fmt.Errorf("cannot use all zeroes as a preimage")

	// Prevent the hash of the unknown preimage magic value to be used for a
	// hold invoice. This would make it impossible to settle the invoice,
	// because it would still be interpreted as not having a preimage.
	case invoice.Hash != nil &&
		*invoice.Hash == channeldb.UnknownPreimage.Hash():

		return nil, nil,
			fmt.Errorf("cannot use hash of all zeroes preimage")

	// If no hash or preimage is given, generate a random preimage.
	case invoice.Preimage == nil && invoice.Hash == nil:
		if _, err := rand.Read(paymentPreimage[:]); err != nil {
			return nil, nil, err
		}
		paymentHash = paymentPreimage.Hash()

	// If just a hash is given, we create a hold invoice by setting the
	// preimage to unknown.
	case invoice.Preimage == nil && invoice.Hash != nil:
		paymentPreimage = channeldb.UnknownPreimage
		paymentHash = *invoice.Hash

	// A specific preimage was supplied. Use that for the invoice.
	case invoice.Preimage != nil && invoice.Hash == nil:
		paymentPreimage = *invoice.Preimage
		paymentHash = invoice.Preimage.Hash()
	}

	// The size of the memo, receipt and description hash attached must not
	// exceed the maximum values for either of the fields.
	if len(invoice.Memo) > channeldb.MaxMemoSize {
		return nil, nil, fmt.Errorf("memo too large: %v bytes "+
			"(maxsize=%v)", len(invoice.Memo), channeldb.MaxMemoSize)
	}
	if len(invoice.Receipt) > channeldb.MaxReceiptSize {
		return nil, nil, fmt.Errorf("receipt too large: %v bytes "+
			"(maxsize=%v)", len(invoice.Receipt), channeldb.MaxReceiptSize)
	}
	if len(invoice.DescriptionHash) > 0 && len(invoice.DescriptionHash) != 32 {
		return nil, nil, fmt.Errorf("description hash is %v bytes, must be %v",
			len(invoice.DescriptionHash), channeldb.MaxPaymentRequestSize)
	}

	// The value of the invoice must not be negative.
	if invoice.Value < 0 {
		return nil, nil, fmt.Errorf("payments of negative value "+
			"are not allowed, value is %v", invoice.Value)
	}

	amtMSat := lnwire.NewMSatFromSatoshis(invoice.Value)

	// The value of the invoice must also not exceed the current soft-limit
	// on the largest payment within the network.
	if amtMSat > cfg.MaxPaymentMSat {
		return nil, nil, fmt.Errorf("payment of %v is too large, max "+
			"payment allowed is %v", invoice.Value,
			cfg.MaxPaymentMSat.ToSatoshis(),
		)
	}

	// We also create an encoded payment request which allows the
	// caller to compactly send the invoice to the payer. We'll create a
	// list of options to be added to the encoded payment request. For now
	// we only support the required fields description/description_hash,
	// expiry, fallback address, and the amount field.
	var options []func(*zpay32.Invoice)

	// We only include the amount in the invoice if it is greater than 0.
	// By not including the amount, we enable the creation of invoices that
	// allow the payee to specify the amount of satoshis they wish to send.
	if amtMSat > 0 {
		options = append(options, zpay32.Amount(amtMSat))
	}

	// If specified, add a fallback address to the payment request.
	if len(invoice.FallbackAddr) > 0 {
		addr, err := btcutil.DecodeAddress(invoice.FallbackAddr,
			cfg.ChainParams)
		if err != nil {
			return nil, nil, fmt.Errorf("invalid fallback address: %v",
				err)
		}
		options = append(options, zpay32.FallbackAddr(addr))
	}

	// If expiry is set, specify it. If it is not provided, no expiry time
	// will be explicitly added to this payment request, which will imply
	// the default 3600 seconds.
	if invoice.Expiry > 0 {

		// We'll ensure that the specified expiry is restricted to sane
		// number of seconds. As a result, we'll reject an invoice with
		// an expiry greater than 1 year.
		maxExpiry := time.Hour * 24 * 365
		expSeconds := invoice.Expiry

		if float64(expSeconds) > maxExpiry.Seconds() {
			return nil, nil, fmt.Errorf("expiry of %v seconds "+
				"greater than max expiry of %v seconds",
				float64(expSeconds), maxExpiry.Seconds())
		}

		expiry := time.Duration(invoice.Expiry) * time.Second
		options = append(options, zpay32.Expiry(expiry))
	}

	// If the description hash is set, then we add it do the list of options.
	// If not, use the memo field as the payment request description.
	if len(invoice.DescriptionHash) > 0 {
		var descHash [32]byte
		copy(descHash[:], invoice.DescriptionHash[:])
		options = append(options, zpay32.DescriptionHash(descHash))
	} else {
		// Use the memo field as the description. If this is not set
		// this will just be an empty string.
		options = append(options, zpay32.Description(invoice.Memo))
	}

	// We'll use our current default CLTV value unless one was specified as
	// an option on the command line when creating an invoice.
	switch {
	case invoice.CltvExpiry > math.MaxUint16:
		return nil, nil, fmt.Errorf("CLTV delta of %v is too large, max "+
			"accepted is: %v", invoice.CltvExpiry, math.MaxUint16)
	case invoice.CltvExpiry != 0:
		options = append(options,
			zpay32.CLTVExpiry(invoice.CltvExpiry))
	default:
		// TODO(roasbeef): assumes set delta between versions
		defaultDelta := cfg.DefaultCLTVExpiry
		options = append(options, zpay32.CLTVExpiry(uint64(defaultDelta)))
	}

	// If we were requested to include routing hints in the invoice, then
	// we'll fetch all of our available private channels and create routing
	// hints for them.
	if invoice.Private {
		openChannels, err := cfg.ChanDB.FetchAllChannels()
		if err != nil {
			return nil, nil, fmt.Errorf("could not fetch all channels")
		}

		graph := cfg.ChanDB.ChannelGraph()

		numHints := 0
		for _, channel := range openChannels {
			// We'll restrict the number of individual route hints
			// to 20 to avoid creating overly large invoices.
			if numHints > 20 {
				break
			}

			// Since we're only interested in our private channels,
			// we'll skip public ones.
			isPublic := channel.ChannelFlags&lnwire.FFAnnounceChannel != 0
			if isPublic {
				continue
			}

			// Make sure the counterparty has enough balance in the
			// channel for our amount. We do this in order to reduce
			// payment errors when attempting to use this channel
			// as a hint.
			chanPoint := lnwire.NewChanIDFromOutPoint(
				&channel.FundingOutpoint,
			)
			if amtMSat >= channel.LocalCommitment.RemoteBalance {
				log.Debugf("Skipping channel %v due to "+
					"not having enough remote balance",
					chanPoint)
				continue
			}

			// Make sure the channel is active.
			if !cfg.IsChannelActive(chanPoint) {
				log.Debugf("Skipping channel %v due to not "+
					"being eligible to forward payments",
					chanPoint)
				continue
			}

			// To ensure we don't leak unadvertised nodes, we'll
			// make sure our counterparty is publicly advertised
			// within the network. Otherwise, we'll end up leaking
			// information about nodes that intend to stay
			// unadvertised, like in the case of a node only having
			// private channels.
			var remotePub [33]byte
			copy(remotePub[:], channel.IdentityPub.SerializeCompressed())
			isRemoteNodePublic, err := graph.IsPublicNode(remotePub)
			if err != nil {
				log.Errorf("Unable to determine if node %x "+
					"is advertised: %v", remotePub, err)
				continue
			}

			if !isRemoteNodePublic {
				log.Debugf("Skipping channel %v due to "+
					"counterparty %x being unadvertised",
					chanPoint, remotePub)
				continue
			}

			// Fetch the policies for each end of the channel.
			chanID := channel.ShortChanID().ToUint64()
			info, p1, p2, err := graph.FetchChannelEdgesByID(chanID)
			if err != nil {
				log.Errorf("Unable to fetch the routing "+
					"policies for the edges of the channel "+
					"%v: %v", chanPoint, err)
				continue
			}

			// Now, we'll need to determine which is the correct
			// policy for HTLCs being sent from the remote node.
			var remotePolicy *channeldb.ChannelEdgePolicy
			if bytes.Equal(remotePub[:], info.NodeKey1Bytes[:]) {
				remotePolicy = p1
			} else {
				remotePolicy = p2
			}

			// If for some reason we don't yet have the edge for
			// the remote party, then we'll just skip adding this
			// channel as a routing hint.
			if remotePolicy == nil {
				continue
			}

			// Finally, create the routing hint for this channel and
			// add it to our list of route hints.
			hint := zpay32.HopHint{
				NodeID:      channel.IdentityPub,
				ChannelID:   chanID,
				FeeBaseMSat: uint32(remotePolicy.FeeBaseMSat),
				FeeProportionalMillionths: uint32(
					remotePolicy.FeeProportionalMillionths,
				),
				CLTVExpiryDelta: remotePolicy.TimeLockDelta,
			}

			// Include the route hint in our set of options that
			// will be used when creating the invoice.
			routeHint := []zpay32.HopHint{hint}
			options = append(options, zpay32.RouteHint(routeHint))

			numHints++
		}

	}

	// Create and encode the payment request as a bech32 (zpay32) string.
	creationDate := time.Now()
	payReq, err := zpay32.NewInvoice(
		cfg.ChainParams, paymentHash, creationDate, options...,
	)
	if err != nil {
		return nil, nil, err
	}

	payReqString, err := payReq.Encode(
		zpay32.MessageSigner{
			SignCompact: cfg.NodeSigner.SignDigestCompact,
		},
	)
	if err != nil {
		return nil, nil, err
	}

	newInvoice := &channeldb.Invoice{
		CreationDate:   creationDate,
		Memo:           []byte(invoice.Memo),
		Receipt:        invoice.Receipt,
		PaymentRequest: []byte(payReqString),
		Terms: channeldb.ContractTerm{
			Value:           amtMSat,
			PaymentPreimage: paymentPreimage,
		},
	}

	log.Tracef("[addinvoice] adding new invoice %v",
		newLogClosure(func() string {
			return spew.Sdump(newInvoice)
		}),
	)

	// With all sanity checks passed, write the invoice to the database.
	_, err = cfg.AddInvoice(newInvoice, paymentHash)
	if err != nil {
		return nil, nil, err
	}

	return &paymentHash, newInvoice, nil
}