<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Wietse Wind</title>
    <description>The latest articles on Forem by Wietse Wind (@wietse).</description>
    <link>https://forem.com/wietse</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F490358%2F2c813068-bf5d-4679-b9b3-9594b31e1e5a.png</url>
      <title>Forem: Wietse Wind</title>
      <link>https://forem.com/wietse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wietse"/>
    <language>en</language>
    <item>
      <title>Hooked #0: Intro</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Thu, 30 Jun 2022 22:27:00 +0000</pubDate>
      <link>https://forem.com/wietse/hooked-0-intro-2bb7</link>
      <guid>https://forem.com/wietse/hooked-0-intro-2bb7</guid>
      <description>&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Please note
&lt;/h5&gt;

&lt;p&gt;Since this blog was published &lt;a href="https://twitter.com/XRPLLabs/status/1545354585430171648"&gt;a lot has happened&lt;/a&gt;. The Hooks Amendment is now running on a &lt;a href="https://xumm.notion.site/Hooks-V2-staging-net-info-XLS20-518fa261c5cd49d2bcb89a5b9e7bef05"&gt;public testnet&lt;/a&gt; and has a &lt;a href="http://hooks.xrpl.org/"&gt;public "Builder" where you (devs) can code Hooks and deploy them to the testnet&lt;/a&gt;, straight from your browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Cross post: this article was posted &lt;a href="https://write.as/xumm/xrpl-labs-is-working-on-the-transaction-hooks-amendment-for-the-xrp-ledger"&gt;here&lt;/a&gt; on July 30th 2020. &lt;a href="https://dev.to/t/xrplhooks/top/infinity"&gt;More blogs have been published since&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  XRPL Labs is working on the transaction "HOOKS" amendment for the XRP Ledger. Supporting business logic integration for developers.
&lt;/h3&gt;

&lt;p&gt;The XRP ledger is known and is being appreciated for its transaction throughput, speed and the low fees. Combined with available advanced transaction types like multi sign, escrows, payment channels and even a decentralized exchange (all on ledger, out of the box, without requiring smart contracts) the XRPL has a lot to offer businesses and (creative) developers.&lt;/p&gt;

&lt;p&gt;At XRPL Labs &lt;a href="https://coil.com/p/XUMM/Post-Beta-The-future-of-XUMM/Wk1hvXOsc"&gt;&lt;strong&gt;we build XUMM&lt;/strong&gt;&lt;/a&gt; (and other, smaller libs. and projects). While building a product &amp;amp; business leveraging just about all things the XRPL has to offer, we’re continuously looking at the XRP ledger from developer, consumer and business perspectives.&lt;/p&gt;

&lt;p&gt;We realized that, while the XRP ledger already has a lot to offer, developers and businesses need a lot of flexibility, allowing them to not only build what is possible today, but to build what they can imagine tomorrow. For XUMM, we’re looking at &lt;strong&gt;&lt;a href="https://coil.com/p/XUMM/Post-Beta-The-future-of-XUMM/Wk1hvXOsc"&gt;tomorrow (and the day after, our three year roadmap and beyond)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think about (just to name a few):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Auto saving on incoming transactions. Automatically park VAT, send a part of your received on ledger pay to your holiday savings account, …&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An on ledger Tip / Gift platform (bot), to individuals, charities, opt in infrastructure (validator) rewards, etc. Using “Lite Accounts”, without account reserves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Lite Accounts” so businesses can assign &amp;amp; track loyalty points for all their customers, on ledger, without having to activate their account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On ledger subscriptions to advisory lists like the &lt;a href="https://xrplorer.com/products/advisorylist"&gt;&lt;strong&gt;XRPForensics&lt;/strong&gt;&lt;/a&gt; list, to auto block incoming &amp;amp; outgoing transactions from and to scams, no matter the used XRP ledger client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storing account based flags, like “did this user perform and passed KYC”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On ledger if/else (or more advanced) conditions on incoming or outgoing payments, based on your own logic, possibly using data provided by oracles&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While envisioning multiple &lt;strong&gt;on ledger&lt;/strong&gt; features (samples below) for XUMM, we quickly realized that most features would be best implemented on ledger, non custodial, as we (and many other developers and businesses) don’t have (or want to get) the appropriate licenses for handling user funds, custody, etc. And we were only talking about the features &lt;strong&gt;we&lt;/strong&gt; could come up with. Imagine what would happen if other businesses, creative developers, use cases out there found their way to a flexible way to add on ledger business logic to transactions on the XRP ledger.&lt;/p&gt;

&lt;p&gt;We decided to call our idea “&lt;strong&gt;Hooks&lt;/strong&gt;”. Transaction Hooks. They are small, efficient pieces of code being defined on an XRPL account, allowing logic to be executed before and/or after XRPL transactions. These hooks can be really simple, like: “reject payments &amp;lt; 10 XRP”, or “for all outgoing payments, send 10% to my savings account” or more advanced. By allowing hooks to not only execute efficient logic but also to store small, simple data objects, one could define a hook like: “for incoming payments transactions, check if the sending account is in a list maintained by another hook, and if present: reject the transaction”.&lt;/p&gt;

&lt;p&gt;We are currently thinking things through, drafting what an implementation would look like. We’re turning that into open source code and a proof of concept, then to develop a first version and run it on our own (private, after that: public) XRPL testnet. We’ll be focussing on everything required to protect the XRP ledger and its future: security, stability, performance &amp;amp; usability (in its broadest sense, for developers, business cases, …). There’s still much to think about and discuss before we will publish more details, like the fee model: how do we enable the Hooks feature without allowing Hooks to be abused to spam the XRPL? Or: what is the Hooks environment going to look like (WebAssembly?). Did we cover all edge cases we can think of, and does the solution &amp;amp; implementation we ended up with support all use cases we initially thought of? Does the solution we come up with scale?&lt;/p&gt;

&lt;p&gt;While we will spend more time brain crunching, designing &amp;amp; coding, we’re really excited we get to work &amp;amp; collaborate with awesome people &amp;amp; technology, in a world where we’re all able to contribute &amp;amp; share ideas, improving &amp;amp; contributing to the open and decentralized XRP ledger. While we still need some time, we are already really excited about engaging with you, devs &amp;amp; businesses, testing, integrating, and hopefully: seeing validators vote for our “Hooks” amendment (to be), at some point in the future.&lt;/p&gt;

</description>
      <category>xrpl</category>
      <category>xrp</category>
      <category>hooks</category>
      <category>xrplhooks</category>
    </item>
    <item>
      <title>Subscribe to live status updates (XUMM PHP SDK)</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Thu, 24 Mar 2022 10:07:54 +0000</pubDate>
      <link>https://forem.com/wietse/subscribe-to-live-status-updates-xumm-php-sdk-5131</link>
      <guid>https://forem.com/wietse/subscribe-to-live-status-updates-xumm-php-sdk-5131</guid>
      <description>&lt;h1&gt;
  
  
  4. Subscribe to live status updates
&lt;/h1&gt;

&lt;p&gt;So far, you've created a payment request, clicked the "next" URL, and scanned the QR code with you XUMM app to approve&lt;br&gt;
or reject the request. Great!&lt;/p&gt;

&lt;p&gt;As an app developer, you can subscribe to your payload's live status updates and react to them. For instance, you can&lt;br&gt;
show the user who created the request a message that says "Payment request accepted! 🎉" when the user on the other end&lt;br&gt;
has signed your request or "Payment request rejected :(️" when it was rejected.&lt;/p&gt;

&lt;p&gt;Let's try and do that.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.1 Create a callback function
&lt;/h3&gt;

&lt;p&gt;One of the things that makes subscribing to status updates so powerful, is that you can pass it a &lt;em&gt;callback function&lt;/em&gt; to&lt;br&gt;
handle the data. The status update data will be passed to your callback as an instance of &lt;br&gt;
&lt;code&gt;Xrpl\XummSdkPhp\Subscription\CallbackParams&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's define your callback at the bottom of your script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CallbackParams&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;?array&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'signed'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Don't do anything, wait for the next message.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'signed'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🎉 Payment request accepted!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Returning a value ends the subscription.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Payment request rejected :(&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Start a subscription
&lt;/h3&gt;

&lt;p&gt;Now let's start a subscription and pass our callback to handle any events that are coming in!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sdk&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$createdPayload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when the user signs or rejects the request (which you can do by following the URL &lt;br&gt;
&lt;a href="https://dev.to/wietse/your-first-payload-xumm-php-sdk-2phg"&gt;as per the last step&lt;/a&gt;), your function will be called and the subscription ended.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.3 Obtain a user token and send a push notification
&lt;/h3&gt;

&lt;p&gt;Let's say that next time we send this user a sign request, we want them to receive a push notification on their phone. &lt;br&gt;
We can do that by obtaining a user token for them and passing that into the next payload. The user token is issued when&lt;br&gt;
they sign their first sign request. We just have to fetch the signed request using the event data we return in our &lt;br&gt;
callback function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; this part uses &lt;a href="http://wiki.commonjs.org/wiki/Promises/A"&gt;Promises&lt;/a&gt;, which is a fairly new concept in &lt;br&gt;
PHP. If you've written async code in JavaScript, you'll be familiar with it.&lt;/p&gt;

&lt;p&gt;Let's wait until the subscription has ended, and then send ourselves another payment request. This time, we'll receive a &lt;br&gt;
push notification on our phone because we pass the user token we've obtained.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$subscription&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;resolved&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sdk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$payloadId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'payload_uuidv4'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$payloadId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$signedRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sdk&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'payload_uuidv4'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

        &lt;span class="nv"&gt;$newRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sdk&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'TransactionType'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Payment'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'Destination'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'rGBiHBoEs238W7H1b4gMey55He97kWcoUb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Use your own address here&lt;/span&gt;
                &lt;span class="s1"&gt;'Amount'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'1000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="nv"&gt;$signedRequest&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;issuedUserToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"The new request was %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$newRequest&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;pushed&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'pushed'&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'not pushed...'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be aware that to test this on your actual phone, you should have push notifications turned on for XUMM. It might also&lt;br&gt;
help to put in a short &lt;code&gt;sleep()&lt;/code&gt; statement before you push the new request, so you have some time to lock your phone and&lt;br&gt;
clearly see the notification coming in.&lt;/p&gt;

&lt;p&gt;-- &lt;/p&gt;

&lt;p&gt;Credits: thank you &lt;a href="https://github.com/paulinevos/xumm-php-sdk-tutorial"&gt;Pauline&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>xumm</category>
      <category>sdk</category>
      <category>php</category>
      <category>xrpl</category>
    </item>
    <item>
      <title>Your first payload (XUMM PHP SDK)</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Thu, 24 Mar 2022 10:07:53 +0000</pubDate>
      <link>https://forem.com/wietse/your-first-payload-xumm-php-sdk-2phg</link>
      <guid>https://forem.com/wietse/your-first-payload-xumm-php-sdk-2phg</guid>
      <description>&lt;h1&gt;
  
  
  3. Your first payload
&lt;/h1&gt;

&lt;p&gt;Now that we've established a connection to the XUMM platform using the SDK, it's time to send something we can sign. &lt;br&gt;
We'll send a "transaction template" to the XUMM platform, called a Payload. The lifecycle of a Payload is explained in &lt;br&gt;
more detail in &lt;a href="https://xumm.readme.io/docs/payload-workflow"&gt;the XUMM API documentation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, create a payload by instantiating an instance of &lt;code&gt;Xrpl\XummSdkPhp\Payload\Payload&lt;/code&gt;. It &lt;strong&gt;must&lt;/strong&gt; contain a &lt;br&gt;
transaction body array formatted as per &lt;a href="https://xrpl.org/transaction-types.html"&gt;XRP ledger specifications&lt;/a&gt;. It &lt;strong&gt;can&lt;/strong&gt;&lt;br&gt;
contain a user token, options, and some custom metadata.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.1 Create a payload
&lt;/h3&gt;

&lt;p&gt;Our first payload will be a Payment transaction type. This is a very minimal example of a payload you can send to XUMM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Xrpl\XummSdkPhp\Payload\Payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'TransactionType'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Payment'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'Destination'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'rwietsevLFg8XSmG3bEZzFein1g8RBqWDZ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Use your own address here&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If, like in the minimal example above, no amount is entered, the end user will be able to select the currency and amount&lt;br&gt;
to send in XUMM after opening the sign request. You could also add more details to your payload, as per the following &lt;br&gt;
example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;transactionBody&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'TransactionType'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Payment'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'Destination'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'rwietsevLFg8XSmG3bEZzFein1g8RBqWDZ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Use your own address here&lt;/span&gt;
        &lt;span class="s1"&gt;'Amount'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'10000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;immutable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;customMeta&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomMeta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nb"&gt;uniqid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'Hi! Can you pay me please? Thanks! ❤️'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Send the payload
&lt;/h3&gt;

&lt;p&gt;Now you can pass your &lt;code&gt;Payload&lt;/code&gt; object to &lt;code&gt;XummSdk::createPayload&lt;/code&gt; and show the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$createdPayment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sdk&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$payment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$createdPayment&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sign request: ${url}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Re-run your script to see it work! You can now follow the URL in the result and scan the QR code to sign the request,&lt;br&gt;
or reject it.&lt;/p&gt;

&lt;p&gt;The first time you send a user a sign request, they'll always have to scan the QR code. Once they've signed it, you can&lt;br&gt;
obtain a user token for that user and send them push notifications on future sign requests! Let's see how that's done&lt;br&gt;
in the next chapter:&lt;/p&gt;

&lt;p&gt;Next: &lt;a href="https://dev.to/wietse/subscribe-to-live-status-updates-xumm-php-sdk-5131"&gt;4. Subscribe to live status updates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-- &lt;/p&gt;

&lt;p&gt;Credits: thank you &lt;a href="https://github.com/paulinevos/xumm-php-sdk-tutorial"&gt;Pauline&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>xumm</category>
      <category>php</category>
      <category>sdk</category>
      <category>xrpl</category>
    </item>
    <item>
      <title>Project setup (XUMM PHP SDK)</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Thu, 24 Mar 2022 10:07:51 +0000</pubDate>
      <link>https://forem.com/wietse/project-setup-xumm-php-sdk-263n</link>
      <guid>https://forem.com/wietse/project-setup-xumm-php-sdk-263n</guid>
      <description>&lt;h1&gt;
  
  
  2. Project setup
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Previous: &lt;a href="https://dev.to/wietse/xumm-sdk-1-get-your-xumm-api-credentials-5c3i"&gt;1. Create XUMM API credentials&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The tutorial project has a little script that will use the SDK as a dependency. Right now, it returns a &lt;br&gt;
&lt;code&gt;Hello World&lt;/code&gt; response. Let's run it in our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php ./start.php   &lt;span class="c"&gt;# Start server listening to port 8080 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see &lt;code&gt;Hello World&lt;/code&gt;. Great! Any time you make changes to your project during this tutorial, you'll run the&lt;br&gt;
script to see the changes.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.1 Include the SDK
&lt;/h3&gt;

&lt;p&gt;Use composer to add the XUMM PHP SDK as a dependency to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require xrpl/xumm-sdk-php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Add your credentials
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note: this is the only part that won't be included in the code solution of this chapter, as everybody's credentials are&lt;br&gt;
unique.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Assign the credentials you created in &lt;br&gt;
&lt;a href="https://dev.to/wietse/xumm-sdk-1-get-your-xumm-api-credentials-5c3i"&gt;Step 1&lt;/a&gt;&lt;br&gt;
to the &lt;code&gt;XUMM_API_KEY&lt;/code&gt; and &lt;code&gt;XUMM_API_SECRET&lt;/code&gt; environment variables (be aware you need to do this on every new terminal &lt;br&gt;
session):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;XUMM_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{your API key}"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;XUMM_API_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{your API secret}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 Use the XUMM SDK
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;start.php&lt;/code&gt;, include composer's &lt;code&gt;autoload&lt;/code&gt; file at the top of the script, so that your script can find the &lt;code&gt;XummSdk&lt;/code&gt; &lt;br&gt;
class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;require_once&lt;/span&gt; &lt;span class="s1"&gt;'./vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now instantiate the &lt;code&gt;XummSdk&lt;/code&gt;. It will source your credentials from the environment variables you set in step 2.2.&lt;br&gt;
To test the SDK, call &lt;code&gt;XummSdk::ping&lt;/code&gt; and show the application name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$sdk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;Xrpl\XummSdkPhp\XummSdk&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$pong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sdk&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Application name: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$pong&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when you run your script your should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Application name: &lt;span class="o"&gt;{&lt;/span&gt;your app name&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 It works!&lt;/p&gt;

&lt;p&gt;Next: &lt;a href="https://dev.to/wietse/your-first-payload-xumm-php-sdk-2phg"&gt;3. Your first payload&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-- &lt;/p&gt;

&lt;p&gt;Credits: thank you &lt;a href="https://github.com/paulinevos/xumm-php-sdk-tutorial"&gt;Pauline&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>xumm</category>
      <category>php</category>
      <category>xrpl</category>
      <category>sdk</category>
    </item>
    <item>
      <title>Using the XUMM PHP SDK (tutorial)</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Thu, 24 Mar 2022 10:07:47 +0000</pubDate>
      <link>https://forem.com/wietse/using-the-xumm-php-sdk-tutorial-o70</link>
      <guid>https://forem.com/wietse/using-the-xumm-php-sdk-tutorial-o70</guid>
      <description>&lt;p&gt;In a nutshell, the &lt;a href="https://xumm.readme.io/docs/call-xumm-platform"&gt;XUMM API&lt;/a&gt; allows developers to deliver sign requests&lt;br&gt;
to their app's users, to create new transactions on the XRP ledger.&lt;/p&gt;

&lt;p&gt;XUMM end users can then &lt;a href="https://www.youtube.com/watch?v=P6hL1FDvF4c"&gt;scan a QR code&lt;/a&gt; or receive a push notification to &lt;br&gt;
open the sign request. When they approve it, XUMM signs it, and the transaction is placed on the ledger.&lt;/p&gt;

&lt;p&gt;To make it easier to interact with the API, XUMM released an SDK in a number of languages, &lt;br&gt;
&lt;a href="https://github.com/XRPL-Labs/XUMM-SDK-PHP"&gt;most recently in PHP&lt;/a&gt;. This tutorial explains how to use it. Every chapter &lt;br&gt;
will have a branch with the code solution in the tutorial's Git repository. So if you get stuck, just &lt;code&gt;git &lt;br&gt;
checkout ch-2&lt;/code&gt;, &lt;code&gt;git checkout ch-3&lt;/code&gt;, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;For this tutorial, we assume you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;basic knowledge of PHP and the terminal&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getcomposer.org/doc/00-intro.md"&gt;composer&lt;/a&gt; installed on your machine&lt;/li&gt;
&lt;li&gt;PHP^8.1 (the SDK's required PHP version) installed on your machine&lt;/li&gt;
&lt;li&gt;the XUMM app on your phone, and an account&lt;/li&gt;
&lt;li&gt;XUMM Developer credentials. You can &lt;a href="https://dev.to/wietse/xumm-sdk-1-get-your-xumm-api-credentials-5c3i"&gt;register them at the XUMM Developer Console&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-- &lt;/p&gt;

&lt;p&gt;Credits: thank you &lt;a href="https://github.com/paulinevos/xumm-php-sdk-tutorial"&gt;Pauline&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>xumm</category>
      <category>php</category>
      <category>xrpl</category>
      <category>sdk</category>
    </item>
    <item>
      <title>XUMM 1.1 » 2.0 » 3.0 - Update 🎉</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Thu, 08 Apr 2021 11:44:04 +0000</pubDate>
      <link>https://forem.com/wietse/xumm-1-1-2-0-3-0-update-jda</link>
      <guid>https://forem.com/wietse/xumm-1-1-2-0-3-0-update-jda</guid>
      <description>&lt;p&gt;Those who followed the recent developments at &lt;a href="https://xrpl-labs.com" rel="noopener noreferrer"&gt;XPRL Labs&lt;/a&gt;, as Tweeted by &lt;a href="https://twitter.com/XRPLLabs" rel="noopener noreferrer"&gt;XRPL Labs&lt;/a&gt;, &lt;a href="https://twitter.com/XummWallet" rel="noopener noreferrer"&gt;XUMM&lt;/a&gt; &amp;amp; the XRPL Labs founder &lt;a href="https://twitter.com/WietseWind" rel="noopener noreferrer"&gt;Wietse&lt;/a&gt;, know they can expect a &lt;strong&gt;significant XUMM update&lt;/strong&gt; in the coming days.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tl;dr
 • XUMM 1.1 will be called 2.0 released in April 2021
     • This includes CSC migration support &amp;amp; tool
 • XUMM 2.0 will be 3.0, released in Q2~3 2021
 • We're introducing xApps, aggregating the XRPL ecosystem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;h3&gt;
  
  
  1.1: Not a 'dot one' release
&lt;/h3&gt;

&lt;p&gt;The coming update has been referred to as "XUMM 1.1". The coming (soon) update did indeed started out as a 'dot one' release. However, while we were coding a couple of cool new features to add to the &lt;a href="https://support.xumm.app/hc/en-us/articles/360018569240-XUMM-1-0-0-V1-" rel="noopener noreferrer"&gt;lastest (first public, final, non-beta) XUMM 1.0 release&lt;/a&gt; we decided to add a couple of significant new features to the 1.1 release we were already developing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.0: Profiles &amp;amp; opt-in KYC
&lt;/h3&gt;

&lt;p&gt;Halfway last year ('20) we &lt;a href="https://coil.com/p/XUMM/Post-Beta-The-future-of-XUMM/Wk1hvXOsc" rel="noopener noreferrer"&gt;published our roadmap for XUMM&lt;/a&gt;, referring to a "XUMM 2.0" release around Q1 2021. XUMM 2.0 would introduce XUMM Pro, with 'opt in KYC', verified profile pages, hosted PayString, payment requests, transaction push notifications and some other cool features.&lt;/p&gt;

&lt;h1&gt;
  
  
  Vision: the ecosystem
&lt;/h1&gt;

&lt;p&gt;While working on XUMM 1.1 features, our vision expanded. XUMM has the opportunity to do more than offer kick ass non custodial wallet features to end users. XUMM could (also) already empower &lt;a href="https://dev.to/wietse/how-to-use-the-xumm-sdk-in-node-js-5380"&gt;developers to interact with end users&lt;/a&gt; (through '&lt;a href="https://xumm.readme.io/docs/payload-workflow" rel="noopener noreferrer"&gt;sign requests&lt;/a&gt;', using the &lt;a href="https://www.npmjs.com/package/xumm-sdk" rel="noopener noreferrer"&gt;XUMM SDK&lt;/a&gt;).&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg024o9h8f6ijoaovh0ry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg024o9h8f6ijoaovh0ry.png" alt="XUMM XRPL Ecosystem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why not take the collaboration / integration between XUMM and the entire XRP Ledger ecosystem to the next level by allowing curated 3rd party XRPL ecosystem developers to put their own tools &amp;amp; XRPL apps straight into the hands of XUMM users?&lt;/p&gt;

&lt;p&gt;What if XRPL ecosystem developers could build tools ('apps') then to offer them in a unified user interface &lt;strong&gt;inside XUMM&lt;/strong&gt;? A great user experience for end users, while both users &amp;amp; developers don't have to worry about key management. XUMM takes care of security &amp;amp; signing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hi 'xApps' 👋 - "XRPL/XUMM Apps"
&lt;/h2&gt;

&lt;p&gt;We figured developing exactly this would be win-win-win:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Other developers can offer their tools to end users in a secure, trusted environment: XUMM, without spending a single second on (private) key management.&lt;/li&gt;
&lt;li&gt;End users get access to more on ledger features &amp;amp; tools, a better user experience (unified) &amp;amp; don't have to trust their keys to any other app. &lt;/li&gt;
&lt;li&gt;More time for XRPL Labs to focus on core XUMM &amp;amp; XUMM Platform development, with more and more features being added to XUMM by trusted 3rd party developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvm7js86083baenz263x0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvm7js86083baenz263x0.png" alt="XUMM xApps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We &lt;a href="https://github.com/XRPL-Labs/XUMM-Issue-Tracker/issues/302" rel="noopener noreferrer"&gt;wrote&lt;/a&gt; &lt;a href="https://github.com/XRPL-Labs/XUMM-Issue-Tracker/issues/303" rel="noopener noreferrer"&gt;drafts&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/XRPL-Labs/XUMM-Issue-Tracker/issues/307" rel="noopener noreferrer"&gt;coded&lt;/a&gt; some more.&lt;/p&gt;
&lt;h2&gt;
  
  
  Developing xApps
&lt;/h2&gt;

&lt;p&gt;While adding xApp support to XUMM, we made a list of xApps to develop ourselves, using standard web technologies (HTML, CSS). To offer new features to end users &amp;amp; showcase xApps to users &amp;amp; developers. We came up with xApps to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure &lt;a href="https://xrpl-labs.com/tangem/origin:2030bloga" rel="noopener noreferrer"&gt;Tangem Card&lt;/a&gt; back up cards&lt;/li&gt;
&lt;li&gt;"Merge" on ledger accounts (AccountDelete)&lt;/li&gt;
&lt;li&gt;Issue tokens on the XRPL&lt;/li&gt;
&lt;li&gt;Create escrows&lt;/li&gt;
&lt;li&gt;Trade (more advanced, limit orders) on the XRPL Decentralized Exchange (DEX)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(We have some more ideas, but with only 24 hours in a day we could only select a couple of them).&lt;/p&gt;

&lt;p&gt;We realized some of the trusted, appreciated XRPL community developers built some of the tools on our list, like &lt;a href="https://twitter.com/nixerFFM" rel="noopener noreferrer"&gt;@nixerFFM&lt;/a&gt;'s &lt;a href="https://xumm.community" rel="noopener noreferrer"&gt;xumm.community&lt;/a&gt;, &lt;a href="https://twitter.com/TowoLabs" rel="noopener noreferrer"&gt;Towo Labs&lt;/a&gt;'s &lt;a href="https://www.xrptoolkit.com" rel="noopener noreferrer"&gt;XRP Toolkit&lt;/a&gt; and what about &lt;a href="https://twitter.com/Gatehub" rel="noopener noreferrer"&gt;@Gatehub&lt;/a&gt;'s awesome DEX &lt;a href="https://gatehub.net" rel="noopener noreferrer"&gt;trading interface&lt;/a&gt;? We pitched our xApps vision &amp;amp; invited them to build. And guess what? They did!&lt;/p&gt;
&lt;h2&gt;
  
  
  Welcome home CSC 🤗
&lt;/h2&gt;

&lt;p&gt;Still working on XUMM 1.1, realizing that what we were working on would result in an update not worthy of a 'dot one' label, we were talking to a couple of familiar &amp;amp; respected people from the CSC (CasinoCoin) team. We talked about how their project, running on technology forked from the XRP Ledger, would benefit from migrating back onto the XRP Ledger.&lt;/p&gt;

&lt;p&gt;In the years since their fork the XRP Ledger improved and advanced: it's more decentralized than ever, scalable infrastructure is being provided by multiple parties, new features are introduced and voted in by independent validators and with the upcoming &lt;a href="https://coil.com/p/XUMM/XRPL-Labs-is-working-on-the-transaction-HOOKS-amendment-for-the-XRP-Ledger-Supporting-business-logic/kEmqhoqMW" rel="noopener noreferrer"&gt;Hooks amendment&lt;/a&gt;, smart contract features &lt;a href="https://dev.to/t/xrplhooks/top/infinity"&gt;may even be available natively&lt;/a&gt; on the XRP Ledger in the future.&lt;/p&gt;

&lt;p&gt;The cherry on top? XUMM would be available -out of the box- for the project's end users &amp;amp; partners. Offering a user friendly, secure &amp;amp; actively developed non custodial wallet &amp;amp; launchpad for CSC ecosystem xApps &amp;amp; online + retail integrations using xApps and the XUMM platform.&lt;/p&gt;

&lt;p&gt;It didn't take much time for the CSC team to make a decision 😉. At XRPL Labs, we offered to build a token migration wizard. &lt;strong&gt;We could use our own technology to build it: a CSC migration xApp&lt;/strong&gt;. Eating our own dogfood, our xApps implementation evolved and improved while we were building both the XUMM update &amp;amp; the xApp.&lt;/p&gt;
&lt;h1&gt;
  
  
  Planning &amp;amp; roadmap
&lt;/h1&gt;

&lt;p&gt;Closing in on the end of our XUMM update development cycle, we realized that XUMM 1.1 actually became XUMM 2.0 - be it with different features (and quite some changes/updates under the hood making the implementation of our original planned 2.0 release easier to develop). &lt;strong&gt;We changed, fixed &amp;amp; added &lt;a href="https://github.com/XRPL-Labs/XUMM-Issue-Tracker/projects/4#column-11694097" rel="noopener noreferrer"&gt;a total of 120 (!!) things&lt;/a&gt;&lt;/strong&gt;. We updated the app, our platform, our infrastructure and our developer SDK. On top of that, we &lt;a href="https://twitter.com/WietseWind/status/1377530608793092097" rel="noopener noreferrer"&gt;introduced&lt;/a&gt;, &lt;a href="https://xumm.readme.io/docs/xapps" rel="noopener noreferrer"&gt;documented&lt;/a&gt; &amp;amp; built &lt;a href="https://twitter.com/XummCommunity/status/1380139977883979778" rel="noopener noreferrer"&gt;xApp support&lt;/a&gt; &amp;amp; our own xApps, and added a feature allowing XRPL forks to &lt;a href="https://twitter.com/WietseWind/status/1375281841125552136" rel="noopener noreferrer"&gt;migrate back to the XRPL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We feel our upcoming XUMM release kicks off a new chapter. Characterized by convergence &amp;amp; increased collaboration between XRPL ecosystem players, XRPL community developers and XUMM end users, with XUMM &amp;amp; the XRPL as the binding factor. We're &lt;em&gt;aggregating&lt;/em&gt; the ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/Arturo_P_A/status/1356574723434512386" rel="noopener noreferrer"&gt;@Arturo_P_A worded our own vision&lt;/a&gt; even better than we would have been able to do it ourselves:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1356574723434512386-776" src="https://platform.twitter.com/embed/Tweet.html?id=1356574723434512386"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1356574723434512386-776');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1356574723434512386&amp;amp;theme=dark"
  }



&lt;iframe class="tweet-embed" id="tweet-1356585362395660291-231" src="https://platform.twitter.com/embed/Tweet.html?id=1356585362395660291"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1356585362395660291-231');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1356585362395660291&amp;amp;theme=dark"
  }



&lt;iframe class="tweet-embed" id="tweet-1356587875610017792-888" src="https://platform.twitter.com/embed/Tweet.html?id=1356587875610017792"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1356587875610017792-888');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1356587875610017792&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h1&gt;
  
  
  Changing version numbers
&lt;/h1&gt;

&lt;h4&gt;
  
  
  At the risk of confusing our users, we feel we &lt;strong&gt;must&lt;/strong&gt; amend our version numbers &amp;amp; roadmap.
&lt;/h4&gt;

&lt;p&gt;What we originally planned for a 2.0 release will be released ~mid 2021 in XUMM 3.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  XUMM 3.0
&lt;/h2&gt;

&lt;p&gt;Our ~mid 2021 XUMM release with features as originally presented in &lt;a href="https://coil.com/p/XUMM/Post-Beta-The-future-of-XUMM/Wk1hvXOsc" rel="noopener noreferrer"&gt;our mid 2020 blog post&lt;/a&gt; will be &lt;strong&gt;XUMM 3.0&lt;/strong&gt;, featuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XUMM Pro (€50 / $60 per year)&lt;/li&gt;
&lt;li&gt;Opt in KYC&lt;/li&gt;
&lt;li&gt;Verified Profiles &amp;amp; Payment Request pages&lt;/li&gt;
&lt;li&gt;Hosted PayString (previously called: PayID)&lt;/li&gt;
&lt;li&gt;More (interesting) xApps, by XRPL Labs &amp;amp; other companies &amp;amp; developers from the XRPL ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  A note on releasing xApps
&lt;/h4&gt;

&lt;p&gt;xApps don't depend on a specific XUMM release version, so the can be published and updated on the go (rolling releases) without end users having to update their XUMM app. Expect us to do that (together with other XRPL devs). We'll be introducing new xApps &lt;strong&gt;between&lt;/strong&gt; XUMM releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exit 1.1, long live XUMM 2.0
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhklmnhe6xvgi73yc020.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhklmnhe6xvgi73yc020.png" alt="XUMM Dark Mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our upcoming XUMM release (April 2021) will be &lt;strong&gt;XUMM 2.0&lt;/strong&gt;, featuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;xApps&lt;/li&gt;
&lt;li&gt;Dark mode&lt;/li&gt;
&lt;li&gt;Payment requests (request XRP or fiat amount converted to XRP)&lt;/li&gt;
&lt;li&gt;Currency &lt;strong&gt;rate&lt;/strong&gt; conversion (XRP - fiat): secify fiat amount, send XRP equivalent&lt;/li&gt;
&lt;li&gt;Improved (community provided) translations &amp;amp; more languages&lt;/li&gt;
&lt;li&gt;Account re-ordering &amp;amp; hiding (eg. hide inactive Regular Key accounts)&lt;/li&gt;
&lt;li&gt;Improved Decentralized Exchange transaction presentation in the transaction list (Events)&lt;/li&gt;
&lt;li&gt;NFT support (&lt;a href="https://github.com/XRPLF/XRPL-Standards/discussions/30" rel="noopener noreferrer"&gt;XLS-14d&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Included xApps:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://xrpl-labs.com/tangem/origin:2030blogb" rel="noopener noreferrer"&gt;Tangem card&lt;/a&gt; 'Back Up' (Regular Key)&lt;/li&gt;
&lt;li&gt;Account merge (AccountDelete)&lt;/li&gt;
&lt;li&gt;Escrow creator (by &lt;a href="https://twitter.com/nixerffm" rel="noopener noreferrer"&gt;@nixerFFM&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Token creator (issuer) (by &lt;a href="https://twitter.com/nixerffm" rel="noopener noreferrer"&gt;@nixerFFM&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Importing alternative alphabet secrets &amp;amp; CSC Migration Wizard (with XUMM KYC)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We already developed a couple of important features required for XUMM 3.0: they are present (but hidden) in XUMM 2.0, so we can start testing XUMM 3.0 features with selected* (see note below) community members. This allows us to work our way towards a fast and smooth XUMM 3.0 release later this year. &lt;/p&gt;

&lt;p&gt;We hope you understand we had to update our version numbering, and we're sorry for possible confusion we cause by doing so. Please allow us to make up for it with a boatload of improvements &amp;amp; awesome new features 😎&lt;/p&gt;




&lt;p&gt;* Selected community members (early XUMM 3.0 feature (testing / beta) access are: well known XRPL ecosystem (development/business) contributors &amp;amp; all users who &lt;a href="https://xrpl-labs.com/tangem/origin:2030blog" rel="noopener noreferrer"&gt;purchase(d) the XUMM Tangem 4 card or 5 card card pack&lt;/a&gt;, including "Early XUMM Pro Beta Access".&lt;/p&gt;

</description>
      <category>xumm</category>
      <category>xrpl</category>
      <category>xapps</category>
      <category>wallet</category>
    </item>
    <item>
      <title>Hooked #5: Consensus</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Fri, 05 Feb 2021 13:26:29 +0000</pubDate>
      <link>https://forem.com/wietse/hooked-5-consensus-23o2</link>
      <guid>https://forem.com/wietse/hooked-5-consensus-23o2</guid>
      <description>&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Please note
&lt;/h5&gt;

&lt;p&gt;Since this blog was published &lt;a href="https://twitter.com/XRPLLabs/status/1545354585430171648"&gt;a lot has happened&lt;/a&gt;. The Hooks Amendment is now running on a &lt;a href="https://xumm.notion.site/Hooks-V2-staging-net-info-XLS20-518fa261c5cd49d2bcb89a5b9e7bef05"&gt;public testnet&lt;/a&gt; and has a &lt;a href="http://hooks.xrpl.org/"&gt;public "Builder" where you (devs) can code Hooks and deploy them to the testnet&lt;/a&gt;, straight from your browser.&lt;/p&gt;
&lt;h3&gt;
  
  
  Warning: this is a highly technical blog 🤓 🤓 🤓
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The Story So Far...
&lt;/h1&gt;

&lt;p&gt;In Q4 of 2020 we released a &lt;a href="https://dev.to/wietse/hooked-3-tech-preview-release-play-with-smart-contracts-on-the-xrp-ledger-2076"&gt;Tech Preview of Hooks.&lt;/a&gt; This preview consisted of a docker container which would run a single instance of &lt;code&gt;xrpld-hooks&lt;/code&gt; in &lt;a href="https://xrpl.org/rippled-server-modes.html#reasons-to-run-a-rippled-server-in-stand-alone-mode"&gt;stand-alone mode&lt;/a&gt;. As the name implies this was for the purpose of demonstrating how hooks will look in the future (without being a production-ready amendment.) Since then we have successfully replaced the web assembly runtime engine &lt;code&gt;Wasmer&lt;/code&gt; with &lt;code&gt;SSVM&lt;/code&gt; as part of a drive toward production grade efficiency. (&lt;a href="https://dev.to/wietse/hooked-4-every-microsecond-counts-1lpc"&gt;See our previous blog&lt;/a&gt;.)&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing Consensus
&lt;/h1&gt;

&lt;p&gt;The 'stand-alone' mode of our Q4 2020 Tech Preview release meant that &lt;code&gt;xrpld&lt;/code&gt; did not not communicate with other validators. It is a singular centralised validator &lt;em&gt;simulating&lt;/em&gt; a decentralised ledger. This simulation is very useful for debugging and demonstrating behaviour, but &lt;strong&gt;achieving real consensus is very important&lt;/strong&gt;.  Without consensus the project can never produce live decentralised ledgers and therefore can never go into production on the live network. To begin tests of consensus we span up a two private testnet validators at our office.&lt;/p&gt;

&lt;p&gt;At our first try everything worked as planned (🎉!) except for emitted transactions (that's fixed now). &lt;strong&gt;Emitted transactions are produced when a hook exercises its right to create new transactions separate to the triggering (original) transaction&lt;/strong&gt;: for example the carbon hook emits a 1% payment to a carbon offset address every time the owner of the account sends a payment to someone. This is an &lt;strong&gt;emitted&lt;/strong&gt; transaction. &lt;/p&gt;

&lt;h1&gt;
  
  
  Emission and Dispute
&lt;/h1&gt;

&lt;p&gt;On our internal testnet the '&lt;a href="https://github.com/RichardAH/rippled-hooks/blob/hooks-ssvm/hook-api-examples/carbon/carbon.c"&gt;carbon hook&lt;/a&gt;' fired correctly on both validators and produced the same output. However a race condition emerged due to the way emitted transactions are queued for application to the next ledger.&lt;/p&gt;

&lt;p&gt;Our initial strategy for emitting transactions was to insert the emitted transaction directly into the transaction queue, through &lt;code&gt;xrpld's&lt;/code&gt; network interface, as though it were submitted by a special user.&lt;/p&gt;

&lt;p&gt;One validator would always produce the emitted transaction slightly sooner than the other, and it would propose that transaction to the other validator. The other validator would not be able to find the transaction and would request a copy of it. The first validator would send a copy but the second validator would reject it and mark it as bad because emitted transactions cannot be received over the network (since they lack signatures this would be a massive security issue.)&lt;/p&gt;

&lt;p&gt;As a result one validator would always have the emitted transaction and the other would never have it, therefore no consensus could be reached on emitted transactions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Consensus Protocol to the Rescue
&lt;/h1&gt;

&lt;p&gt;In most cases of consensus failure the answer is to use a consensus protocol to achieve agreement between otherwise disagreeing parties. Fortunately we don't need to reinvent the wheel here, &lt;code&gt;xrpld&lt;/code&gt; already contains a consensus protocol called the Ripple Consensus Protocol.&lt;/p&gt;

&lt;p&gt;To achieve consensus on emitted transactions we now emit them into a special &lt;code&gt;directory&lt;/code&gt; on the ledger itself rather than emitting them directly into the transaction queue. This means all validators have a chance to produce and agree on what the emitted transactions indeed are before they attempt to queue them for application to a future ledger.&lt;/p&gt;

&lt;p&gt;Now when a transaction triggers a hook which in turn emits a transaction, the validated triggering (originating) transaction's metadata looks like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The closed ledger looks like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Processing Emitted Transactions
&lt;/h1&gt;

&lt;p&gt;To apply the emitted transactions to the next ledger &lt;code&gt;xrpld-hooks&lt;/code&gt; reads the directory created above as soon as the last ledger closes, and injects those validly emitted and agreed upon transactions into the next ledger at the time it is created. This way, provided the validators achieved agreement on the last ledger they already have accepted the emitted transactions in the next ledger.&lt;/p&gt;

&lt;p&gt;Common transaction fields have been modified to optionally include &lt;code&gt;FirstLedgerSequence&lt;/code&gt; (as distinct from &lt;code&gt;LastLedgerSequence&lt;/code&gt;which is already present in all transactions). &lt;code&gt;FirstLedgerSequence&lt;/code&gt; is now mandatory on all emitted transactions. To begin with the field will always point to the next ledger (that is: the ledger &lt;em&gt;after&lt;/em&gt; the ledger in which the transaction was emitted.) However in future it may be changed to allow a validator-votable figure. In short: this prevents emitted transactions being applied (executed) in the same ledger they were emitted, which could otherwise produce infinite loops (e.g. a hook emits a tx which triggers a hook which emits a tx etc.)&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;FirstLedgerSequence&lt;/code&gt; is expanded it will allow validators to hold emitted transactions for future execution some specified number of ledgers later. This can be useful for on-chain bots, for example: Automated Market Makers which might need to periodically wake themselves up to do internal accounting even when they are not triggered by any external party.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cleanup
&lt;/h1&gt;

&lt;p&gt;The triggering (originating) transaction causes the emitted transaction to be added to the emission directory on the ledger. But once added that entry also needs to be removed or &lt;code&gt;xrpld&lt;/code&gt; will continue to attempt to apply the same emitted transaction to every future ledger.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;xrpld&lt;/code&gt; ledgers are modified by transactions. It's not possible to &lt;em&gt;just clean up&lt;/em&gt; the old emitted transactions. The modification of the ledger to delete the nodes associated with those emitted transactions in the emission directory needs to be &lt;code&gt;caused by&lt;/code&gt; some transaction.&lt;/p&gt;

&lt;p&gt;Fortunately we have a transaction: the emitted transaction! Every emitted transaction executes a callback to the hook that emitted it. This is important because without a callback the hook would have trouble knowing if its emitted transactions were eventually accepted by the network (and therefore whether or not, for example, a payment actually occured.)&lt;/p&gt;

&lt;p&gt;Callbacks allow the hook to do internal accounting, modify its own state, and importantly now also automatically trigger a cleanup on the emission directory for that transaction. Callbacks cannot emit transactions or cause transactions to be rejected.&lt;/p&gt;

&lt;p&gt;A validated emitted transaction now looks like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Calling all Hook Developers
&lt;/h1&gt;

&lt;p&gt;Are you a developer interested in writing hooks? Would you like to share what you've built or ask questions? &lt;/p&gt;

&lt;p&gt;Please check the &lt;a href="https://dev.to/search?q=hooked%20xrpl&amp;amp;filters=class_name:Article"&gt;other blogs&lt;/a&gt;, the &lt;a href="https://github.com/XRPL-Labs/xrpld-hooks/tree/hooks-chaining/hook-api-examples"&gt;source &amp;amp; README's&lt;/a&gt; and ... just a &lt;strong&gt;little&lt;/strong&gt; more patience as we're on track for a Q1 public testnet release :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;Discussions: &lt;a href="https://github.com/XRPL-Labs/xrpld-hooks/discussions"&gt;here »&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Next Steps
&lt;/h1&gt;

&lt;p&gt;We are drawing close to public testnet. Some edge and corner cases still need to be debugged with emitted transactions, and the &lt;code&gt;slot&lt;/code&gt; component of the Hooks API (which allows hooks to request and read all sorts of different data from the ledger) needs to be finished. We are well on track for a Q1 testnet release 🎉 😎&lt;/p&gt;




&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@pawel_czerwinski?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Paweł Czerwiński&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/agreement?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>hooks</category>
      <category>xrplhooks</category>
      <category>xrpl</category>
    </item>
    <item>
      <title>Auto Reconnect(ing) OpenVPN client connections on EdgeOS</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Fri, 29 Jan 2021 16:08:00 +0000</pubDate>
      <link>https://forem.com/wietse/auto-reconnect-ing-openssh-client-connections-on-edgeos-d9c</link>
      <guid>https://forem.com/wietse/auto-reconnect-ing-openssh-client-connections-on-edgeos-d9c</guid>
      <description>&lt;p&gt;EdgeOS should automatically reconnect your OpenVPN client tunnel. If it doesn't, there are two things you can add to your OpenVPN client config that will make the client reconnect when it's down (eg. because the server or your internet connection has been down).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can let your EdgeOS router ping over the VPN connection, and if it's down, reconnect it&lt;/li&gt;
&lt;li&gt;Tell EdgeOS (OpenVPN client) not to store Auth Tokens, and always perform full auth after reconnecting.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Especially #2 is a problem for some, and hard to debug. You know this is happening if your log files show something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep "AUTH" /var/log/messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Response:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;messages:Month Day Time Hostname openvpn[id]: AUTH: Received control message: AUTH_FAILED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add the &lt;code&gt;ping&lt;/code&gt; setting to ping and auto-reconnect, and tell the EdgeOS OpenVPN client to ignore 'auth tokens' received (for a full re-auth on reconnect) assuming your OpenVPN client tunnel is &lt;code&gt;vtun1&lt;/code&gt;. Then commit, save and exit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configure
set interfaces openvpn vtun1 openvpn-option "--ping 10"
set interfaces openvpn vtun1 openvpn-option "--ping-restart 60"
set interfaces openvpn vtun1 openvpn-option "--pull-filter ignore auth-token"
commit; save; exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optionally you can add these settings to your &lt;code&gt;.ovpn&lt;/code&gt; client config as well, without the prefixed double dash. Eg. edit your client &lt;code&gt;.ovpn&lt;/code&gt; file, and add these lines to your client config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ping 10
ping-restart 60
pull-filter ignore auth-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>edgeos</category>
      <category>edgerouter</category>
      <category>ubiquiti</category>
      <category>router</category>
    </item>
    <item>
      <title>Force Reconnect OpenVPN client connections (commandline) on EdgeOS</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Fri, 29 Jan 2021 15:55:33 +0000</pubDate>
      <link>https://forem.com/wietse/force-reconnect-openvpn-client-connections-commandline-on-edgeos-5akc</link>
      <guid>https://forem.com/wietse/force-reconnect-openvpn-client-connections-commandline-on-edgeos-5akc</guid>
      <description>&lt;p&gt;If your EdgeOS router has one or more OpenVPN &lt;strong&gt;client&lt;/strong&gt; connections configured, you may want to restart the OpenVPN connection at some point. Either because it is down and somehow doesn't come back and you want to force that, or because you simply want it to restart (and pick up new settings / IP / ...).&lt;/p&gt;

&lt;p&gt;In the EdgeOS web interface you can simply disable and re enable the VPN interface, but on the commandline it's not that easy.&lt;/p&gt;

&lt;p&gt;Let's say your OpenVPN client connection is &lt;code&gt;vtun1&lt;/code&gt;. To restart the connection the easy way, simply create (you can do this the easy way after &lt;a href="https://dev.to/wietse/install-nano-on-edgeos-2-x-3e7j"&gt;installing the nano text editor&lt;/a&gt;)a script somewhere (eg. in &lt;code&gt;/config/scripts&lt;/code&gt;. Let's call it &lt;code&gt;restart-ovpn.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The contents of the &lt;code&gt;restart-ovpn.sh&lt;/code&gt; file (assuming your SSH client connection is &lt;code&gt;vtun1&lt;/code&gt;) should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper begin
/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper set interfaces openvpn vtun1 disable
/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper commit
/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper delete interfaces openvpn vtun1 disable
/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper commit
/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper end
logger -t piareset openvpn restarted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This scripts start a config session, disables the OpenVPN client, commits, deletes the disable flag, commits again, ends the config session and then writes a logline (for future reference).&lt;/p&gt;

&lt;p&gt;You can now make the script executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x restart-ovpn.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and the next time you want to restart your OpenVPN client connection on the commandline, simply run (from the folder where you created the &lt;code&gt;restart-ovpn.sh&lt;/code&gt; file):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./restart-ovpn.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>edgeos</category>
      <category>edgerouter</category>
      <category>ubiquiti</category>
      <category>router</category>
    </item>
    <item>
      <title>Reload BGP routes / configuration on your EdgeRouter</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Fri, 29 Jan 2021 15:43:37 +0000</pubDate>
      <link>https://forem.com/wietse/reload-bgp-routes-configuration-on-your-edgerouter-19k2</link>
      <guid>https://forem.com/wietse/reload-bgp-routes-configuration-on-your-edgerouter-19k2</guid>
      <description>&lt;p&gt;So you updated your BGP configuration and your EdgeRouter doesn't reflect your updates? Or the BGP service seems to have stopped and doesn't come back?&lt;/p&gt;

&lt;p&gt;You run into this if you have BGP configured, but all &lt;code&gt;show ip bgp&lt;/code&gt; commands return nothing, eg.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;show ip bgp summary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... results in just a newline and even stopping* &amp;amp; starting* the BGP service doesn't help.&lt;/p&gt;

&lt;p&gt;A workaround is to save your existing config, delete the bgp settings, &lt;code&gt;commit&lt;/code&gt; (that'll get EdgeOS to disable BGP), reload (&lt;code&gt;load&lt;/code&gt;) your config (with BGP settings), &lt;code&gt;commit&lt;/code&gt; (that'll get EdgeOS to restart EdgeOS with the most recent BGP config).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configure
save
delete protocol bgp
commit
load
commit
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  *) Starting/Stopping the BGP service
&lt;/h3&gt;

&lt;p&gt;When not in a &lt;code&gt;configure&lt;/code&gt; session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/init.d/vyatta-quagga stop bgpd
/etc/init.d/vyatta-quagga start bgpd
# or:
/etc/init.d/vyatta-quagga force-reload bgpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>edgeos</category>
      <category>edgerouter</category>
      <category>ubiquiti</category>
      <category>router</category>
    </item>
    <item>
      <title>Enable key based SSH login to your EdgeRouter</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Fri, 29 Jan 2021 15:37:08 +0000</pubDate>
      <link>https://forem.com/wietse/enable-key-based-ssh-login-to-your-edgerouter-4c01</link>
      <guid>https://forem.com/wietse/enable-key-based-ssh-login-to-your-edgerouter-4c01</guid>
      <description>&lt;p&gt;If you want to login to your EdgeOS router using your SSH identity instead of a password, you can. Make sure you already have your SSH identity (key, pubkey). You'll need your pubkey later on to whitelist it in your EdgeOS config.&lt;/p&gt;

&lt;p&gt;To configure SSH login using your your ssh key instead of a password, SSH into your EdgeRouter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh {your-webinterface-username}@{your-router-ip} -p 22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eg. &lt;code&gt;ssh johndoe@192.168.1.1 -p 22&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When logged in, start configuration mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tutorial assumes your username (to access the EdgeOS web interface (and SSH, just now)) is &lt;code&gt;johndoe&lt;/code&gt;, replace &lt;code&gt;johndoe&lt;/code&gt; with your actual username.&lt;/p&gt;

&lt;p&gt;Now configure your SSH login key type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set system login user johndoe authentication public-keys johndoe@device type ssh-rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eg. &lt;code&gt;set system login user myAdminAccount authentication public-keys myAdminAccount@myMacbook type ssh-rsa&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now add your public key. The value to add after &lt;code&gt;key&lt;/code&gt; in the command below should be the Base64 string that's usually in your &lt;code&gt;id_rsa.pub&lt;/code&gt;, without the &lt;code&gt;ssh-rsa&lt;/code&gt; prefix, and without the hostname@device appended.&lt;/p&gt;

&lt;p&gt;On OSX you can get this value using:&lt;br&gt;
&lt;code&gt;cat ~/.ssh/id_rsa.pub|cut -d " " -f 2&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set system login user johndoe authentication public-keys johndoe@device key AAAAB.........
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now commit your settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open a second terminal window to check if you can sign in using your SSH identity, without a password. If everything works, you can save &amp;amp; exit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;save; exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Done 🎉
&lt;/h3&gt;

</description>
      <category>edgeos</category>
      <category>edgerouter</category>
      <category>ubiquiti</category>
      <category>router</category>
    </item>
    <item>
      <title>Install `nano` on EdgeOS (2.x)</title>
      <dc:creator>Wietse Wind</dc:creator>
      <pubDate>Fri, 29 Jan 2021 15:05:10 +0000</pubDate>
      <link>https://forem.com/wietse/install-nano-on-edgeos-2-x-3e7j</link>
      <guid>https://forem.com/wietse/install-nano-on-edgeos-2-x-3e7j</guid>
      <description>&lt;p&gt;If you want to edit a (config) file on EdgeOS (2.X.X), you can. EdgeOS comes with &lt;code&gt;vi&lt;/code&gt;. Not the easiest editor to get started with, especially if you just want to update a simple setting in eg. a OpenVPN client config file.&lt;/p&gt;

&lt;p&gt;To make editing the occasional file a bit easier, you can install the &lt;code&gt;nano&lt;/code&gt; package from the Debian repositories. To do that, SSH into your EdgeRouter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh {your-webinterface-username}@{your-router-ip} -p 22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eg. &lt;code&gt;ssh johndoe@192.168.1.1 -p 22&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When logged in, start configuration mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now set the Debian system package, by issuing these commands in the configuration mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set system package repository stretch components 'main contrib non-free' 
set system package repository stretch distribution stretch
set system package repository stretch url http://http.us.debian.org/debian
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configuration by committing, save and exit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit; save; exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now update the system package cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Do &lt;em&gt;NOT&lt;/em&gt; upgrade system packages, that will break some of the packages your EdgeRouter depends on!
&lt;/h3&gt;

&lt;p&gt;You can now install &lt;code&gt;nano&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install nano
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;nano&lt;/code&gt; is installed, we can remove the apt-cache, and remove the Debian repository again from the config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rm -R /var/lib/apt/lists
sudo rm -R /var/cache/apt/archives
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the configuration mode again, and remove the Debian system package repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configure
delete system package repository stretch
commit; save; exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enjoy using &lt;code&gt;nano&lt;/code&gt; for a quick config file edit :)
&lt;/h3&gt;

</description>
      <category>edgeos</category>
      <category>edgerouter</category>
      <category>ubiquiti</category>
      <category>router</category>
    </item>
  </channel>
</rss>
