<html>
<head>
    <title>TLV shop - buy stickers atomically over the Lightning Network</title>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
          integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body class="bg-light">

<div class="container">

    <div class="py-5">
        <div class="text-center">
            <h1>Welcome to <a href="https://tlvshop.com">tlvshop.com</a>!</h1>
            <p class="lead">
                Buy stickers atomically over the Lightning Network
                <br/><br/>
                <span style="color: red">
                    <strong>Update April 15 2020</strong>:
                    This was an interesting experiment, thanks to everyone who participated. We ran out of stickers and
                    have now disabled the shop. While this website still works, you won't be able to order stickers
                    anymore.<br/><br/>
                    All successfully placed orders have been fulfilled.
                </span>
            </p>
        </div>
        <div class="mb-5"></div>

        <p>
            This is not an ordinary webshop. There is no browser, no shopping
            cart, no checkout page and no credit card required. What is it then?
            It is a 100% pure Lightning shop, possibly one of the first of its
            kind.
            <br/><br/>
            Pure Lightning means that the only communication between buyer and us is a
            Lightning payment. Since the introduction of custom tlv records
            (hence the name <a href="https://tlvshop.com">tlvshop.com</a>), it
            is possible to attach arbitrary data to a payment. You can use this new
            functionality to attach a delivery address to the payment.
            <br/><br/>
            Users of <code>LND</code> are able to order, pay for and get stickers delivered
            with just a single <code>lncli</code>
            command. The same privacy guarantees that apply to a Lightning
            payment will also apply to your order details.

            <br/><br/>
            The current offering is rather limited. In fact the only article that we
            currently sell is a set of three cool "RUN LND" stickers:<br/>
        </p>
        <div class="text-center">
            <img src="runlnd.png" alt="RUN LND" width="300" style="margin: 15px"><br/>
            <small>
                Sticker design by
                <a href="https://twitter.com/send_bitcoins">@send_bitcoins</a>/<a href="https://sendbitcoin.lol">sendbitcoin.lol</a>,
                inspired by <a href="https://github.com/wbobeirne/run-lnd-store">github.com/wbobeirne/run-lnd-store</a>
            </small>
        </div>
        <br/>
        <p>
            We don't advertize a price for the set of stickers. We could
            announce a price right here on this page, but that would go against
            the idea of pure Lightning. Ideally a price list would be obtainable
            through Lightning, but that is difficult to realize with the
            protocol as it is today. As a workaround you can use trial and error
            to discover the current price. Payments with an insufficient amount
            will be cancelled back instantly.

            <br/><br/>
            To make it easy to place an order, an <code>lncli</code> command line generator
            is provided below. Please note that none of what you enter there is sent out from this webpage directly.
            You could download this page and run it offline to be sure.
            <br/><br/>
            Also, make sure you enter your address correctly. If you leave the
            email field blank, we won't be able to contact you.
            <br/><br/>
            Happy buying!
        </p>
    </div>

    <div class="row">
        <div class="col-md-12">
            <h4 class="mb-3">Delivery address</h4>
            <form class="needs-validation" novalidate id="orderform">
                <div class="row">
                    <div class="col-md-6 mb-3">
                        <label for="firstName">First name</label>
                        <input type="text" class="form-control" id="firstName" required>
                        <div class="invalid-feedback">
                            Valid first name is required.
                        </div>
                    </div>
                    <div class="col-md-6 mb-3">
                        <label for="lastName">Last name</label>
                        <input type="text" class="form-control" id="lastName" required>
                        <div class="invalid-feedback">
                            Valid last name is required.
                        </div>
                    </div>
                </div>

                <div class="mb-3">
                    <label for="address">Address</label>
                    <input type="text" class="form-control" id="address" placeholder="1234 Main St" required>
                    <div class="invalid-feedback">
                        Please enter your shipping address.
                    </div>
                </div>

                <div class="mb-3">
                    <label for="address2">Address 2 <span class="text-muted">(Optional)</span></label>
                    <input type="text" class="form-control" id="address2" placeholder="Apartment or suite">
                </div>

                <div class="row">
                    <div class="col-md-5 mb-3">
                        <label for="country">Country</label>
                        <select class="custom-select d-block w-100" id="country" required>
                            <option value="">Choose...</option>
                        </select>
                        <div class="invalid-feedback">
                            Please select a valid country.
                        </div>
                    </div>
                    <div class="col-md-4 mb-3">
                        <label for="state">State</label>
                        <select class="custom-select d-block w-100" id="state" required>
                            <option value="">Choose...</option>
                        </select>
                        <div class="invalid-feedback">
                            Please provide a valid state.
                        </div>
                    </div>
                    <div class="col-md-3 mb-3">
                        <label for="zip">Zip</label>
                        <input type="text" class="form-control" id="zip" required>
                        <div class="invalid-feedback">
                            Zip code required.
                        </div>
                    </div>
                </div>

                <div class="mb-3">
                    <label for="city">City</label>
                    <input type="text" class="form-control" id="city">
                    <div class="invalid-feedback">
                        Please enter a valid city.
                    </div>
                </div>

                <div class="mb-3">
                    <label for="amount">Amount (sats)</label>
                    <input type="number" class="form-control" id="amount" placeholder="find out">
                    <div class="invalid-feedback">
                        Please enter a valid amount in satoshis.
                    </div>
                </div>

                <div class="mb-3">
                    <label for="email">Email <span class="text-muted">(Optional)</span></label>
                    <input type="email" class="form-control" id="email" placeholder="you@example.com">
                    <div class="invalid-feedback">
                        Please enter a valid email address for shipping updates.
                    </div>
                </div>

            </form>
        </div>

        <div class="col-md-12">
            <h4 class="mb-3">The command to run</h4>

            <div class="mb-3">
                <label for="data">This is the raw order data that will be sent along with the payment:</label>
                <input type="text" class="form-control" id="data" disabled aria-disabled="true">
            </div>
            <p>
                All you need to do is to run the following command which will send a "keysend" payment with the order
                data encoded in hex. If the payment succeeds, the order is submitted.
                If not, try a different price and/or make sure you are able to pay on mainnet.
            </p>
            <kbd id="command"></kbd>
            <textarea id="command-hidden" class="sr-only"></textarea>

            <div class="pb-5"></div>
            <button class="btn btn-secondary" id="copy">Copy command to clipboard</button>
            <div class="pb-5"></div>
            Build your own TLV shop by <a href="https://github.com/joostjager/tlvshop.com">forking this code on
            GitHub</a>.
            <div class="pb-5"></div>
            <div class="pb-5"></div>
        </div>

    </div>
</div>

<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

<script src="countries.js"></script>

<script>

    const dataTypeShippingAddress = 98117121;
    const destinationPubkey = "<node_pubkey>";
    const command = `lncli sendpayment --keysend --dest ${destinationPubkey}`;


    // country/state script by IshanDemon, visit github.com/IshanDemon
    populateCountries("country", "state");

    $(document).ready(function () {
        update();
        $('#orderform input,select').keyup(update).change(update);

        $('#copy').click(function () {
            const cmdEl = document.getElementById('command-hidden');
            cmdEl.select();
            cmdEl.setSelectionRange(0, 99999);
            document.execCommand('copy');
        });
    });

    function update() {
        let firstName = $('#firstName').val();
        let lastName = $('#lastName').val();
        let address = $('#address').val();
        let address2 = $('#address2').val();
        let zip = $('#zip').val();
        let state = $('#state').val();
        let country = $('#country').val();
        let city = $('#city').val();
        let email = $('#email').val();
        let addr = [
            `${firstName} ${lastName}`,
            address, address2,
            `${state} ${zip} ${city}`,
            country,
            email
        ].join('|');
        let amount = $('#amount').val();
        $('#data').val(addr);
        let cmd = '';
        if (!firstName || !lastName || !address || !zip || !amount || !country || !city) {
            cmd = '<please fill in all required fields first>';
        } else {
            cmd = `${command} --data ${dataTypeShippingAddress}=${toHex(addr)} --amt ${amount}`;
        }
        $('#command').text(cmd);
        $('#command-hidden').text(cmd);
    }

    function toHex(str) {
        let hex = '';
        try {
            hex = unescape(encodeURIComponent(str))
                .split('').map(function (v) {
                    return v.charCodeAt(0).toString(16)
                }).join('')
        } catch (e) {
            hex = str;
            console.log('invalid text input: ' + str)
        }
        return hex
    }
</script>
</body>
</html>