diff --git a/README.md b/README.md
index 9c57f8f3037df618278c14b1b8bde7e3f30b7452..ec6fae28f04c6d75c33c7c43fcb192338169cba4 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
 # cesium2s
 
-Cesium 2, running on Substrate
\ No newline at end of file
+Cesium 2, running on Substrate
+
+
+npm install -g yarn @ionic/cli @angular/cli
diff --git a/src/app/services/base.service.ts b/src/app/services/base.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2a6d6b7882a8480990f9c671b54023a2ef8d85b2
--- /dev/null
+++ b/src/app/services/base.service.ts
@@ -0,0 +1,76 @@
+import {Injectable} from "@angular/core";
+import {Platform} from "@ionic/angular";
+import {environment} from "../../environments/environment";
+
+@Injectable()
+export abstract class AppBaseService {
+
+  private readonly _debug: boolean;
+  private readonly _logPrefix: string = null;
+
+  private _started = false;
+  private _startPromise: Promise<void> = null;
+
+
+  get started(): boolean {
+    return this._started;
+  }
+
+  protected constructor(protected platform: Platform, opts?: {
+    logPrefix?: string;
+    name?: string;
+  }) {
+    this._debug = !environment.production;
+    this._logPrefix = (opts && opts.logPrefix) || ("[" + (opts && opts.name || 'base-service') + "] ");
+  }
+
+  start(): Promise<any> {
+    if (this._startPromise) return this._startPromise;
+    if (this._started) return Promise.resolve();
+
+    this._started = false;
+    const now = Date.now();
+    this.info('Starting service...');
+
+    this._startPromise = this.platform.ready()
+      .then(() => this.doStart())
+      .then((result: any) => {
+        this._started = true;
+        this._startPromise = undefined;
+        this.info(`Starting service [OK] in ${Date.now() - now}ms`);
+        return result;
+      })
+      .catch((err) => {
+        this.error('Cannot start:', err);
+        throw err; // Rethrow
+      });
+
+    return this._startPromise;
+  }
+
+  ready(): Promise<boolean> {
+    if (this._started) return Promise.resolve(true);
+    return this.start()
+      .then((_) => {
+        return true;
+      })
+      .catch((err) => {
+        return false;
+      });
+  }
+
+  protected abstract doStart(): Promise<any>;
+
+  protected debug(msg, ...params: any[]) {
+    if (this._debug) console.debug(this._logPrefix + msg, params);
+  }
+  protected info(msg, ...params: any[]) {
+    console.info(this._logPrefix + msg, params);
+  }
+  protected warn(msg, ...params: any[]) {
+    console.warn(this._logPrefix + msg, params);
+  }
+  protected error(msg, ...params: any[]) {
+    console.error(this._logPrefix + msg, params);
+  }
+}
diff --git a/src/app/services/node.service.ts b/src/app/services/node.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6a084f23a06414e630544e16aa0036b32a353eb9
--- /dev/null
+++ b/src/app/services/node.service.ts
@@ -0,0 +1,35 @@
+import {Injectable} from "@angular/core";
+import {Platform} from "@ionic/angular";
+import {AppBaseService} from "./base.service";
+import {ApiPromise, WsProvider} from "@polkadot/api";
+import {web3Accounts, web3Enable, web3FromAddress} from "@polkadot/extension-dapp";
+import {environment} from "../../environments/environment";
+
+@Injectable({providedIn: 'root'})
+export class NodeService extends AppBaseService {
+
+  private _api: ApiPromise;
+
+  get api(): ApiPromise {
+    return this._api
+  }
+
+  constructor(
+    platform: Platform
+  ) {
+    super(platform, {
+      name: 'node-service'
+    });
+  }
+
+  protected async doStart(): Promise<any> {
+    // Construct
+    const wsProvider = new WsProvider('ws://localhost:9944');
+    const api = await ApiPromise.create({ provider: wsProvider });
+
+    // Do something
+    this.info("Connected to Blockchain genesis: " + api.genesisHash.toHex());
+
+    this._api = api;
+  }
+}
diff --git a/src/app/services/platform.service.ts b/src/app/services/platform.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d9e882ae862624b300bfb8c0c7dfa40c535b88d3
--- /dev/null
+++ b/src/app/services/platform.service.ts
@@ -0,0 +1,43 @@
+import {Injectable} from "@angular/core";
+import {Platform} from "@ionic/angular";
+import {AppBaseService} from "./base.service";
+import {NodeService} from "./node.service";
+
+@Injectable({providedIn: 'root'})
+export class PlatformService extends AppBaseService {
+
+  private _mobile: boolean = null;
+  private _touchUi: boolean = null;
+
+
+  get mobile(): boolean {
+    return this._mobile != null ? this._mobile : this.platform.is('mobile');
+  }
+
+  get touchUi(): boolean {
+    return this._touchUi != null ? this._touchUi :
+      (this.mobile || this.platform.is('tablet') || this.platform.is('phablet'));
+  }
+
+  constructor(
+    platform: Platform,
+    private node: NodeService
+  ) {
+    super(platform, {
+      name: 'platform-service'
+    })
+    this.start();
+  }
+
+  async doStart(): Promise<any> {
+
+    this._mobile = this.mobile;
+    this._touchUi = this.touchUi;
+
+    await Promise.all([
+        this.node.start()
+      ]
+    )
+    // TODO: Init required service
+  }
+}
diff --git a/src/app/services/wallet.service.ts b/src/app/services/wallet.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1faa6504242effbdc9df1169323391c944c39ff3
--- /dev/null
+++ b/src/app/services/wallet.service.ts
@@ -0,0 +1,82 @@
+import {Injectable} from "@angular/core";
+import {Platform} from "@ionic/angular";
+import {AppBaseService} from "./base.service";
+import {web3Accounts, web3Enable, web3FromAddress, web3FromSource} from "@polkadot/extension-dapp";
+import {environment} from "../../environments/environment";
+import {NodeService} from "./node.service";
+import {ApiPromise} from "@polkadot/api";
+import {InjectedAccountWithMeta} from "@polkadot/extension-inject/types";
+
+@Injectable({providedIn: 'root'})
+export class WalletService extends AppBaseService {
+
+  accounts: InjectedAccountWithMeta[];
+
+  get api(): ApiPromise {
+    return this.node.api;
+  }
+
+  constructor(
+    platform: Platform,
+    protected node: NodeService
+  ) {
+    super(platform, {
+      name: 'wallet-service'
+    })
+  }
+
+  protected async doStart(): Promise<any> {
+
+    await this.node.ready();
+
+    // returns an array of all the injected sources
+    // (this needs to be called first, before other requests)
+    const extensions = await web3Enable(environment.name);
+    if (extensions.length === 0) {
+      // no extension installed, or the user did not accept the authorization
+      // in this case we should inform the use and give a link to the extension
+      console.debug('No web3 extension found');
+    }
+
+    // returns an array of { address, meta: { name, source } }
+    // meta.source contains the name of the extension that provides this account
+    this.accounts = await web3Accounts();
+
+
+    if (this.accounts?.length === 0) {
+      this.accounts = [{
+        address: '5ESoncgJ42j8WAyh9SBk2ztMZhUzejEZxF93LnZVBCXR77Kg',
+        meta: {
+          name: 'Alice',
+          source: '0xc74be00087825d9f8ba924d38fde43a8e8953c40c8f6a269b8a4ca337fbef7b7'
+        }
+      }]
+    }
+  }
+
+  async transfer() {
+
+    // the address we use to use for signing, as injected
+    const SENDER = this.accounts[0].address;
+
+    // finds an injector for an address
+    //const injector = await web3FromAddress(SENDER);
+    const injector = await web3FromSource(this.accounts[0].meta.source);
+
+    // sign and send our transaction - notice here that the address of the account
+    // (as retrieved injected) is passed through as the param to the `signAndSend`,
+    // the API then calls the extension to present to the user and get it signed.
+    // Once complete, the api sends the tx + signature via the normal process
+    this.api.tx.balances
+      .transfer('5C5555yEXUcmEJ5kkcCMvdZjUo7NGJiQJMS7vZXEeoMhj3VQ', 12)
+      .signAndSend(SENDER, { signer: injector.signer }, (status) => {
+        if (status.isInBlock) {
+          console.log(`Completed at block hash #${status}`);
+        } else {
+          console.log(`Current status: ${status}`);
+        }
+      }).catch((error: any) => {
+      console.log(':( transaction failed', error);
+    });
+  }
+}
diff --git a/src/app/wallet/wallet-routing.module.ts b/src/app/wallet/wallet-routing.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d05d7da8fda09150268f3c00b05e8ea03148b966
--- /dev/null
+++ b/src/app/wallet/wallet-routing.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { WalletPage } from './wallet.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: WalletPage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class WalletPageRoutingModule {}
diff --git a/src/app/wallet/wallet.module.ts b/src/app/wallet/wallet.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..074075ed084d0978eebb723db1434d621d74f02d
--- /dev/null
+++ b/src/app/wallet/wallet.module.ts
@@ -0,0 +1,19 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {FormsModule} from '@angular/forms';
+
+import {IonicModule} from '@ionic/angular';
+
+import {WalletPage} from './wallet.page';
+import {WalletPageRoutingModule} from "./wallet-routing.module";
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    WalletPageRoutingModule
+  ],
+  declarations: [WalletPage]
+})
+export class WalletPageModule {}
diff --git a/src/app/wallet/wallet.page.html b/src/app/wallet/wallet.page.html
new file mode 100644
index 0000000000000000000000000000000000000000..471b35f5fe328c4c76f2b1a6a979c8c3d2a2abf2
--- /dev/null
+++ b/src/app/wallet/wallet.page.html
@@ -0,0 +1,31 @@
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-menu-button></ion-menu-button>
+    </ion-buttons>
+    <ion-title>{{ walletId }}</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <ion-header collapse="condense">
+    <ion-toolbar>
+      <ion-title size="large">{{ walletId }}</ion-title>
+    </ion-toolbar>
+  </ion-header>
+
+  <div id="container">
+
+    <ion-list>
+      <ion-item>
+        <ion-icon slot="start" name="person"></ion-icon>
+        <ion-text>Test</ion-text>
+      </ion-item>
+    </ion-list>
+
+    <ion-button (click)="wallet.transfer()">
+      <ion-icon slot="start" name="paper-plane"></ion-icon>
+      <ion-label>Envoyer</ion-label>
+    </ion-button>
+  </div>
+</ion-content>
diff --git a/src/app/wallet/wallet.page.scss b/src/app/wallet/wallet.page.scss
new file mode 100644
index 0000000000000000000000000000000000000000..281733f194d1a6cca00e20cad7302c7779ffd76b
--- /dev/null
+++ b/src/app/wallet/wallet.page.scss
@@ -0,0 +1,6 @@
+ion-menu-button {
+  color: var(--ion-color-primary);
+}
+
+#container {
+}
diff --git a/src/app/wallet/wallet.page.spec.ts b/src/app/wallet/wallet.page.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4b32923f41adcd8561e39f38f0c1e28e49506ba
--- /dev/null
+++ b/src/app/wallet/wallet.page.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+import { RouterModule } from '@angular/router';
+import { WalletPage } from './wallet.page';
+
+describe('FolderPage', () => {
+  let component: WalletPage;
+  let fixture: ComponentFixture<WalletPage>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ WalletPage ],
+      imports: [IonicModule.forRoot(), RouterModule.forRoot([])]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(WalletPage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/wallet/wallet.page.ts b/src/app/wallet/wallet.page.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6bf5ac25f6215638f215fd36216172c77dd144ff
--- /dev/null
+++ b/src/app/wallet/wallet.page.ts
@@ -0,0 +1,31 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import {WalletService} from "../services/wallet.service";
+
+@Component({
+  selector: 'app-wallet',
+  templateUrl: './wallet.page.html',
+  styleUrls: ['./wallet.page.scss'],
+})
+export class WalletPage implements OnInit {
+  public walletId: string;
+
+  constructor(
+    public  wallet: WalletService,
+    private activatedRoute: ActivatedRoute
+  ) {
+
+    this.load();
+  }
+
+  ngOnInit() {
+    this.walletId = this.activatedRoute.snapshot.paramMap.get('id');
+  }
+
+  async load() {
+    await this.wallet.ready();
+
+
+  }
+
+}
diff --git a/src/environments/environment.class.ts b/src/environments/environment.class.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ae86fa2d8843c58e9226e7f53fe8ce94898ef509
--- /dev/null
+++ b/src/environments/environment.class.ts
@@ -0,0 +1,5 @@
+export interface Environment {
+  name: string;
+  version?: string;
+  production: boolean;
+}