<?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>DEV Community: Farouk Bello</title>
    <description>The latest articles on DEV Community by Farouk Bello (@maverick_3_0).</description>
    <link>https://dev.to/maverick_3_0</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%2F3784820%2F7972b4e7-11d8-4aeb-93cb-4a3a5dc2b578.png</url>
      <title>DEV Community: Farouk Bello</title>
      <link>https://dev.to/maverick_3_0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maverick_3_0"/>
    <language>en</language>
    <item>
      <title>Add Sign in with ToroPass to Your Flutter App on Toronet</title>
      <dc:creator>Farouk Bello</dc:creator>
      <pubDate>Sun, 07 Jun 2026 16:50:22 +0000</pubDate>
      <link>https://dev.to/maverick_3_0/add-sign-in-with-toropass-to-your-flutter-app-on-toronet-50eh</link>
      <guid>https://dev.to/maverick_3_0/add-sign-in-with-toropass-to-your-flutter-app-on-toronet-50eh</guid>
      <description>&lt;p&gt;If you are building a Flutter app on Toronet, one of the hardest things to get right is identity.&lt;/p&gt;

&lt;p&gt;You need a way to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;verify that a user really controls a Toro wallet&lt;/li&gt;
&lt;li&gt;request access to identity data with explicit consent&lt;/li&gt;
&lt;li&gt;avoid collecting raw KYC details directly in every app&lt;/li&gt;
&lt;li&gt;return the result cleanly back into your app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly what ToroPass is for.&lt;/p&gt;

&lt;p&gt;ToroPass is a Toronet-native identity flow made up of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a wallet app for users&lt;/li&gt;
&lt;li&gt;a published Flutter SDK package for third-party apps: &lt;a href="https://pub.dev/packages/toropass_client" rel="noopener noreferrer"&gt;&lt;code&gt;toropass_client&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part for Flutter developers is that you do not need to rebuild the whole stack to use it.&lt;/p&gt;

&lt;p&gt;You can start with the published SDK package and the released ToroPass Wallet APK today.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the SDK Gives You
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/toropass_client" rel="noopener noreferrer"&gt;&lt;code&gt;toropass_client&lt;/code&gt;&lt;/a&gt; is the Flutter integration layer for ToroPass.&lt;/p&gt;

&lt;p&gt;It handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;launching ToroPass Wallet from your app&lt;/li&gt;
&lt;li&gt;sending the authorization request&lt;/li&gt;
&lt;li&gt;listening for the callback into your app&lt;/li&gt;
&lt;li&gt;validating request state&lt;/li&gt;
&lt;li&gt;exchanging the authorization code&lt;/li&gt;
&lt;li&gt;fetching the approved ToroPass profile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, it gives you a "Sign in with ToroPass" flow for Flutter apps on Toronet.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Flow Works
&lt;/h2&gt;

&lt;p&gt;At a high level:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your Flutter app starts an identity request.&lt;/li&gt;
&lt;li&gt;ToroPass Wallet opens.&lt;/li&gt;
&lt;li&gt;The user approves or denies the request.&lt;/li&gt;
&lt;li&gt;ToroPass Wallet deep-links back into your app.&lt;/li&gt;
&lt;li&gt;Your app exchanges the code and reads the approved profile.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This keeps consent inside the wallet and keeps app integration lightweight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the SDK
&lt;/h2&gt;

&lt;p&gt;Add the package to your &lt;code&gt;pubspec.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;toropass_client&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.1.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pub.dev package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pub.dev/packages/toropass_client" rel="noopener noreferrer"&gt;https://pub.dev/packages/toropass_client&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configure a Redirect URI
&lt;/h2&gt;

&lt;p&gt;Your app needs a callback URI so ToroPass Wallet can route the user back after approval or denial.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myapp://oauth/callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will register this in your app and use the same redirect URI when creating your ToroPass OAuth app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start in Flutter
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;ToroPassClient&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ToroPassClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;config:&lt;/span&gt; &lt;span class="n"&gt;ToroPassClientConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;appName:&lt;/span&gt; &lt;span class="s"&gt;'Example App'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;clientId:&lt;/span&gt; &lt;span class="s"&gt;'your_client_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;redirectUri:&lt;/span&gt; &lt;span class="kt"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'myapp://oauth/callback'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;scopes:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;ToroPassScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;kycStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;ToroPassScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;wallet&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;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then trigger the one-call flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;verifyIdentity&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Access token: &lt;/span&gt;&lt;span class="si"&gt;${token.accessToken}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Wallet address: &lt;/span&gt;&lt;span class="si"&gt;${profile.wallet.address}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'TNS name: &lt;/span&gt;&lt;span class="si"&gt;${profile.wallet.tnsName}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthDenied&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'User denied access.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthCancelled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'User cancelled the flow.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthTimeout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ToroPass did not return in time.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthTransportError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthStateMismatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Callback state mismatch.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthorizationCodeReceived&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;break&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;That is the easiest path if you want a single entry point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Flow If You Need More Control
&lt;/h2&gt;

&lt;p&gt;If you want to separate wallet launch, callback handling, and token exchange:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createAuthorizationRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;launched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;launchWallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;state:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&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="n"&gt;launched&lt;/span&gt; &lt;span class="o"&gt;==&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="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ToroPass Wallet is unavailable.'&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;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;waitForCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;launched&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="n"&gt;callback&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ToroPassAuthorizationCodeReceived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exchangeAuthorizationCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;code:&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fetchProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;accessToken:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;debugPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;wallet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;address&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;This is useful if your app needs finer-grained control over the authorization lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Native Setup
&lt;/h2&gt;

&lt;p&gt;Your app needs two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a callback URI scheme like &lt;code&gt;myapp://oauth/callback&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;wallet-scheme discovery for &lt;code&gt;toropass&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Android
&lt;/h3&gt;

&lt;p&gt;Register your callback URI in &lt;code&gt;AndroidManifest.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.VIEW"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.DEFAULT"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.BROWSABLE"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt;
      &lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"myapp"&lt;/span&gt;
      &lt;span class="na"&gt;android:host=&lt;/span&gt;&lt;span class="s"&gt;"oauth"&lt;/span&gt;
      &lt;span class="na"&gt;android:path=&lt;/span&gt;&lt;span class="s"&gt;"/callback"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a visibility query so the app can detect ToroPass Wallet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;queries&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;intent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.VIEW"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt; &lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"toropass"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/intent&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/queries&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  iOS
&lt;/h3&gt;

&lt;p&gt;Register your callback URI in &lt;code&gt;Info.plist&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CFBundleURLTypes&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CFBundleTypeRole&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Editor&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;CFBundleURLSchemes&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;myapp&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allow wallet discovery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;LSApplicationQueriesSchemes&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;toropass&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What You Need Outside the SDK
&lt;/h2&gt;

&lt;p&gt;To complete the flow end to end, you still need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ToroPass Wallet installed on the device&lt;/li&gt;
&lt;li&gt;an OAuth app created through ToroPass Wallet&lt;/li&gt;
&lt;li&gt;your real &lt;code&gt;clientId&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;your app redirect URI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wallet APK:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/maverick0x/toropass/releases/download/wallet-v1.0.1/toropass-wallet-v1.0.1.apk" rel="noopener noreferrer"&gt;https://github.com/maverick0x/toropass/releases/download/wallet-v1.0.1/toropass-wallet-v1.0.1.apk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Matters for Toronet Apps
&lt;/h2&gt;

&lt;p&gt;Without a shared identity layer, every Toronet app has to solve the same problems repeatedly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;wallet identity verification&lt;/li&gt;
&lt;li&gt;consent UX&lt;/li&gt;
&lt;li&gt;KYC-aware onboarding&lt;/li&gt;
&lt;li&gt;secure app-to-app handoff&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ToroPass moves that complexity into a reusable system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;users complete identity actions in a dedicated wallet&lt;/li&gt;
&lt;li&gt;third-party apps request only what they need&lt;/li&gt;
&lt;li&gt;developers integrate through a small Flutter SDK instead of rebuilding identity from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a much better developer experience and a much better privacy model for users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SDK package: &lt;a href="https://pub.dev/packages/toropass_client" rel="noopener noreferrer"&gt;https://pub.dev/packages/toropass_client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Root project README: &lt;a href="https://github.com/maverick0x/toropass/blob/main/README.md" rel="noopener noreferrer"&gt;https://github.com/maverick0x/toropass/blob/main/README.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SDK integration guide: &lt;a href="https://github.com/maverick0x/toropass/blob/main/TOROPASS_SDK_INTEGRATION.md" rel="noopener noreferrer"&gt;https://github.com/maverick0x/toropass/blob/main/TOROPASS_SDK_INTEGRATION.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Example app README: &lt;a href="https://github.com/maverick0x/toropass/blob/main/packages/toropass_client/example/README.md" rel="noopener noreferrer"&gt;https://github.com/maverick0x/toropass/blob/main/packages/toropass_client/example/README.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Wallet APK: &lt;a href="https://github.com/maverick0x/toropass/releases/download/wallet-v1.0.1/toropass-wallet-v1.0.1.apk" rel="noopener noreferrer"&gt;https://github.com/maverick0x/toropass/releases/download/wallet-v1.0.1/toropass-wallet-v1.0.1.apk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;If you are building on Toronet with Flutter, the simplest way to adopt a proper identity flow today is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;install &lt;a href="https://pub.dev/packages/toropass_client" rel="noopener noreferrer"&gt;&lt;code&gt;toropass_client&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;install ToroPass Wallet&lt;/li&gt;
&lt;li&gt;register your OAuth app&lt;/li&gt;
&lt;li&gt;trigger the consent flow from your app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That gives you a working, Toronet-native identity path without having to build the entire infrastructure yourself.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>web3</category>
      <category>oauth</category>
      <category>mobiledev</category>
    </item>
    <item>
      <title>Stop Spanning export PATH Everywhere: Optimize Your Shell Config</title>
      <dc:creator>Farouk Bello</dc:creator>
      <pubDate>Sat, 28 Feb 2026 16:12:49 +0000</pubDate>
      <link>https://dev.to/maverick_3_0/stop-spanning-export-path-everywhere-optimize-your-shell-config-p6f</link>
      <guid>https://dev.to/maverick_3_0/stop-spanning-export-path-everywhere-optimize-your-shell-config-p6f</guid>
      <description>&lt;p&gt;Are you new to Linux? Is your shell config cluttered with export lines at the top, middle, and end? If you type &lt;code&gt;echo $PATH | tr ':' '\n'&lt;/code&gt; and see a wall of duplicate paths, you’re doing it the hard way.&lt;/p&gt;

&lt;p&gt;For those just starting out: your shell config files (like &lt;code&gt;.bashrc&lt;/code&gt; or &lt;code&gt;.zshrc&lt;/code&gt;) are hidden files that control &lt;strong&gt;environment variables&lt;/strong&gt;. The most important one is &lt;code&gt;PATH&lt;/code&gt;—the list of directories where your terminal searches for commands (like &lt;code&gt;node&lt;/code&gt; or &lt;code&gt;python&lt;/code&gt;). Scattered &lt;code&gt;export PATH&lt;/code&gt; lines make this list messy and hard to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Common Mess (What You're Probably Doing Now)
&lt;/h2&gt;

&lt;p&gt;Most guides tell you to add a tool to your path by appending an export line to your ~/.bashrc (Linux) or ~/.zshrc (macOS). Over time, it looks like this:&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;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;           &lt;span class="c"&gt;# Local user bins&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm/versions/node/v20/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  &lt;span class="c"&gt;# Node.js from nvm&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.pyenv/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;           &lt;span class="c"&gt;# Python from pyenv&lt;/span&gt;


&lt;span class="c"&gt;# New tool&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/new-tool/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# And in some cases you might be required to create environment variables&lt;/span&gt;
&lt;span class="c"&gt;# Environment variable for JAVA (NEW)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/java"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Environment variable for Android Sdk (NEW)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/android/Sdk"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ANDROID_HOME&lt;/span&gt;&lt;span class="s2"&gt;/platform_tools:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ANDROID_HOME&lt;/span&gt;&lt;span class="s2"&gt;/build_tools:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# .... repeats for every new tool, cluttering your file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The issues with this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Redundancy&lt;/strong&gt;: You repeat &lt;code&gt;$PATH&lt;/code&gt; constantly, risking a circular reference or a broken string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; It’s hard to see the "priority" of your tools at a glance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clutter:&lt;/strong&gt; Your config file grows to 50+ lines of repetitive code very quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quick check:&lt;/strong&gt; Open your config with &lt;code&gt;nano ~/.bashrc&lt;/code&gt; (or ~/.zshrc), search for "PATH". Is it a mess?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tip: You can reload your shell anytime &lt;code&gt;source ~/.bashrc&lt;/code&gt; or &lt;code&gt;source ~/.zshrc&lt;/code&gt; after adding a new environment variable or path variable.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Arrays are Better
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;PATH&lt;/code&gt; is just a colon-separated string: &lt;code&gt;/usr/bin:/home/user/bin&lt;/code&gt;. Linux searches this string from &lt;strong&gt;left to right&lt;/strong&gt;. If you have two versions of a tool, the one appearing first in the string wins.&lt;/p&gt;

&lt;p&gt;By using an &lt;strong&gt;array&lt;/strong&gt;, we can manage our paths as a clean, numbered list and join them together at the very end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Clean Solution
&lt;/h2&gt;

&lt;p&gt;Instead of multiple exports, use this block at the end of your config file. It separates the &lt;strong&gt;variables&lt;/strong&gt; from the &lt;strong&gt;list&lt;/strong&gt;.&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="c"&gt;## Define Environment Variables&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/java"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANDROID_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/android/Sdk"&lt;/span&gt;

&lt;span class="c"&gt;## Consolidate into a Path Array&lt;/span&gt;
&lt;span class="c"&gt;# NB: In Zsh, the 'path' array is automatically linked to 'PATH'&lt;/span&gt;
&lt;span class="nv"&gt;my_paths&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin"&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm/versions/node/v20/bin"&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.pyenv/bin"&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/new-tool/bin"&lt;/span&gt; &lt;span class="c"&gt;# New tool&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin"&lt;/span&gt;     &lt;span class="c"&gt;# Java binaries&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ANDROID_HOME&lt;/span&gt;&lt;span class="s2"&gt;/platform_tools"&lt;/span&gt; &lt;span class="c"&gt;# Android platform binaries&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ANDROID_HOME&lt;/span&gt;&lt;span class="s2"&gt;/build_tools"&lt;/span&gt;    &lt;span class="c"&gt;# Android build tool binaries&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# This way you can handle the order&lt;/span&gt;

&lt;span class="c"&gt;## The Logic&lt;/span&gt;
&lt;span class="c"&gt;# If you are using ZSH (Mac default), just add this:&lt;/span&gt;
&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="nv"&gt;$my_paths&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;@] &lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;PATH

&lt;span class="c"&gt;# If you are using BASH (Linux default), use this instead:&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;p &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_paths&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$p&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done
&lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;PATH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pro-Tip:&lt;/strong&gt; Always backup your config before editing:&lt;br&gt;
&lt;code&gt;cp ~/.bashrc ~/.bashrc.backup&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;Ditch 20+ messy exports for one readable array. Your shell config stay clean as you add tools—perfect for Linux/MacOS newcomers. Test it, share it with your friends, and drop a comment with your wins!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does your PATH look like? Drop a comment below if this helped you clean up your terminal!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>coding</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
