We have developed around 50+ blockchain projects and helped companies to raise funds.
You can connect directly to our Stellar  Blockchain developers using any of the above links.

Talk  to Stellar Developer

How To Create a Stellar Wallet

Stellar is one of the top ten cryptocurrencies for international transactions and investments. According to their profile, Stellar aims to connect people to low-cost financial services to combat poverty. This is hardly surprising given that Lumen (XLM) is administered by a non-profit cryptocurrency services provider.

Stellar's price is predicted to rise over the next several months. Thus it would be prudent to purchase Stellar XLM as an investment or use it in your transactions. But what would the ideal wallet look like? Numerous cryptocurrency wallets on the market support Stellar LXM.

We already know that Stellar smart contract combines transactions and numerous limitations to produce the desired outcome. Stellar Smart Contract (SSC) is expressed as the composition of performed and connected transactions by applying various constraints. This tutorial will provide an overview of the finest wallets on the market and how to choose the best wallet for your needs.

What is A Blockchain Wallet?

A blockchain wallet is a cryptocurrency wallet that allows users to handle several types of cryptocurrencies, such as Bitcoin or Ethereum. A blockchain wallet facilitates the exchange of funds. Because transactions are cryptographically signed, they are secure. The wallet is accessible via web devices, including mobile devices, and the user's privacy and identification are protected. As a result, a blockchain wallet includes all the characteristics required for safe and secure fund transfers and exchanges between multiple parties.

It is similar to sending or receiving money through PayPal or any other modern gateway, except that you use cryptocurrencies. The Electrum, Blockchain.info, Jaxx, Mycelium, Samurai, and Bitcoin paper wallets are examples of blockchain wallets. There are many more, depending on your demands and the level of security you desire.

Types of Blockchain Wallets

There are two types of private-key-based blockchain wallets: hot wallets and cold wallets. Hot wallets are comparable to the wallets we carry for daily transactions and are user-friendly. Cold wallets resemble vaults in that they hold bitcoins in a highly secure manner.

Hot wallets are online wallets that facilitate the rapid transmission of cryptocurrencies. They can be found online. Coinbase and Blockchain.info are examples. Cold wallets are offline digital wallets in which transactions are signed offline and exposed online. They are not stored in the cloud on the internet; instead, they are stored offline for security purposes. Trezor and Ledger are some examples of cold wallets.

Private keys are saved in the cloud with hot wallets for speedier transfers. Private keys for cold wallets are kept on hardware that is not connected to the internet, the cloud, or paper. Hot wallets are accessible online 24 hours a day, seven days a week, via a desktop or mobile device, but there is the potential of irrecoverable theft if hacked. With cold wallets, the transaction process safeguards the wallet from illegal access (hacking and other online vulnerabilities).

We can further divide wallets into three categories:

  • Software-based wallets
  • Hardware wallets that you connect to your USB flash drive; and
  • Typical paper-based wallets, for which you print off your public and private keys and store them securely

Coding a Stellar Non-Custodial Blockchain Wallet

We will utilize a toolchain known as StencilJS. It offers the best of modern frontend frameworks and reduces everything to small, quick, and standard-based web components compatible with all browsers. It facilitates the creation of web applications and allows you to observe the entire process of generating a Stellar wallet.

User Flow

To get started, open the terminal and create a new project.

				
					npm init stencil
				
			

A prompt will display for selecting the project type. We are working with modular components, not the entire application, so choose components. Now hurry:

				
					$ npm run generate
				
			

This step will initiate a script for component generation. Enter stellar-wallet.

				
					% npm run generate
> stellar-wallet generate
> stencil generate
$ stencil generate stellar-wallet
				
			

The subsequent files have been created.

				
					- src/components/wallet/wallet.tsx
- src/components/wallet/wallet.css
				
			

Now, instead of CSS, we're using SCSS for styling.

				
					npm i -D @stencil/postcss @stencil/sass autoprefixer @types/autoprefixer rollup-plugin-node-polyfills
				
			

After installing the style packages, open stencil.config.ts and edit it as follows:

				
					import { Config } from "@stencil/core";
import { sass } from "@stencil/sass";
import { postcss } from "@stencil/postcss";
import autoprefixer from "autoprefixer";
import nodePolyfills from "rollup-plugin-node-polyfills";
export const config: Config = {
namespace: "stellar-wallet",
outputTargets: [
{
type: "dist",
esmLoaderPath: "../loader",
},
{
type: "docs-readme",
},
{
type: "www",
serviceWorker: null, // disable service workers
},
],
globalStyle: "src/global/style.scss",
commonjs: {
namedExports: {
"stellar-sdk": [
"StrKey",
"xdr",
"Transaction",
"Keypair",
"Networks",
"Account", "TransactionBuilder",
"BASE_FEE",
"Operation",
"Asset",
"Memo",
"MemoHash",
],
"@stellar/wallet-sdk": ["KeyManager", "KeyManagerPlugins", "KeyType"],
},
},
plugins: [
nodePolyfills(),
sass(),
postcss({
plugins: [autoprefixer()],
}),
],
nodeResolve: {
browser: true,
preferBuiltins: true,
},
};


				
			

Save each style file and update the wallet.tsx file.

Non-custodial wallets do not require communication with servers or databases; all actions are completed locally on the user's device. The intended basic user flow is: "Create account UI modal popup requesting PINcode." Entering the Pincode encrypts a new secret Stellar keypair, and saves the encrypted key to local storage. Every time a page is reloaded, the 'public key' is retrieved so the user can log into their account. For any protected action, such as "CopySecret," the modal will reappear and request the initial passphrase.

Scale your Stellar projects with us

Coding a Popup Modal

Our new component will implement the browser's prompt feature for the popup modal. Create a new component first:

				
					npm run generate
				
			

Name it stellar-immediate. Open the src/components/prompt folder and rename the.css file to.scss. In that style sheet, enter:

				
					@import "../../global/style.scss";

:host {
display: block;
font-family: $font-family;
font-size: 15px;

.prompt-wrapper {
sidebar_position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
align-content: center;
min-height: 100vh;
min-width: 100vw;
background-color: rgba(black, 0.2);
z-index: 1;
}
.prompt {
background-color: white;
padding: 20px;
max-width: 350px;
width: 100%;
sidebar_position: relative;

p {
margin-bottom: 10px;
}
input {
width: 100%;
margin: 0;
padding: 5px;
outline: none;
bsidebar_position: 1px solid black;
text-transform: uppercase;

&:focus {
border-color: blue;
}
}
}
.select-wrapper {
sidebar_position: relative;
display: inline-flex;

select {
border-color: blue;
padding: 0 10px;
min-width: 100px;
}

&:after,
&:before {
font-size: 12px;
sidebar_position: absolute;
right: 10px;
color: blue;
}
&:after {
content: "◀";
top: calc(50% - 5px);
transform: translate(0, -50%) rotate(90deg);
}
&:before {
content: "▶";
top: calc(50% + 5px);
transform: translate(0, -50%) rotate(90deg);
}
}
.actions {
display: flex;
justify-content: flex-end;
margin-top: 10px;

button {
margin: 0;
min-width: 50px;
}
.cancel {
background: none;
bsidebar_position: 1px solid blue;
color: blue;
}
.submit {
margin-left: 10px;
}
}
}

				
			

Name it as stellar-prompt. Open the src/components/prompt folder and rename the.css file to.scss. In that style sheet, enter:

				
					import { Component, Prop, Element, Watch, h, State } from "@stencil/core";
import { defer as loDefer } from "lodash-es";

export interface Prompter {
show: boolean;
message?: string;
placeholder?: string;
options?: Array<any>;
resolve?: Function;
reject?: Function;
}

@Component({
tag: "stellar-prompt",
styleUrl: "prompt.scss",
shadow: true,
})
export class Prompt {
@Element() private element: HTMLElement;

@Prop({ mutable: true }) prompter: Prompter;

@State() private input: string;

@Watch("prompter")
watchHandler(newValue: Prompter, oldValue: Prompter) {
if (newValue.show === oldValue.show) return;

if (newValue.show) {
this.input = null;

if (newValue.options)
this.input =
this.input ||
`${newValue.options[0].code}:${newValue.options[0].issuer}`;
else
loDefer(() => this.element.shadowRoot.querySelector("input").focus());
} else {
this.prompter.message = null;
this.prompter.placeholder = null;
this.prompter.options = null;
}
}

componentDidLoad() {
addEventListener("keyup", (e: KeyboardEvent) => {
if (this.prompter.show)
e.keyCode === 13
? this.submit(e)
: e.keyCode === 27
? this.cancel(e)
: null;
});
}

cancel(e: Event) {
e.preventDefault();

this.prompter = {
...this.prompter,
show: false,
};
this.prompter.reject(null);
}

submit(e: Event) {
e.preventDefault();

this.prompter = {
...this.prompter,
show: false,
};
this.prompter.resolve(this.input);
}

update(e) {
this.input = e.target.value.toUpperCase();
}

render() {
return this.prompter.show ? (
<div class="prompt-wrapper">
<div class="prompt">
{this.prompter.message ? <p>{this.prompter.message}</p> : null}

{this.prompter.options ? (
<div class="select-wrapper">
<select onInput={(e) => this.update(e)}>
{" "}
{this.prompter.options.map((option) => (
<option
value={`${option.code}:${option.issuer}`}
selected={this.input === `${option.code}:${option.issuer}`}
>
{option.code}
</option>
))}
</select>
</div>
) : (
<input
type="text"
placeholder={this.prompter.placeholder}
value={this.input}
onInput={(e) => this.update(e)}
></input>
)}

<div class="actions">
<button
class="cancel"
type="button"
onClick={(e) => this.cancel(e)}
>
Cancel
</button>
<button
class="submit"
type="button"
onClick={(e) => this.submit(e)}
>
OK
</button>
</div>
</div>
</div>
) : null;
}
}

				
			

Make certain to import lodash-es before proceeding:

				
					npm i -D lodash-es
				
			

Coding a Stellar Account Class

				
					interface StellarAccount {
publicKey: string;
keystore: string;
}

				
			

The StellarAccount class includes the public key. Set account and prompter states using the StellarAccount and Prompter classes, respectively.

				
					@Component({
tag: 'stellar-wallet',
styleUrl: 'wallet.scss',
shadow: true
})
export class Wallet {
@State() account: StellarAccount
@State() prompter: Prompter = {show: false}
@State() error: any = null
...}

				
			

Following this, the imported events and methods must be assigned.

				
					import { handleError } from "@services/error";
import { get } from "@services/storage";
export default async function componentWillLoad() {
try {
let keystore = await get("keyStore");
this.error = null;
if (keystore) {
keystore = atob(keystore);
const { publicKey } = JSON.parse(atob(JSON.parse(keystore).adata));
this.account = {
publicKey,
keystore,
};
}
} catch (err) {
this.error = handleError(err);
}
}

				
			

Before drawing the component, componentWillLoad prefills the state and props data. Create the two files below and place them in the src/services directory.

				
					mkdir -p src/services
touch src/services/{error,storage}.ts

				
			

error.ts will contain the following information:

				
					import { get as loGet } from "lodash-es";
export function handleError(err: any) {
return loGet(err, "response.data", loGet(err, "message", err));
}

				
			

It is a straightforward error handler used to handle API requests.

Setting Up Key Storage

Modify storage.ts as follows:

				
					import { Plugins } from "@capacitor/core";
const { Storage } = Plugins;
export async function set(key: string, value: any): Promise<void> {
await Storage.set({
key,
value,
});
}
export async function get(key: string): Promise<any> {
const item = await Storage.get({ key });
return item.value;
}
export async function remove(key: string): Promise<void> {
await Storage.remove({ key });
}

</void></any></void>

				
			

Install and configure the @capacitor/core package.

				
					# Install dependencies
npm i -D @capacitor/core @capacitor/cli
# Initialize Capacitor
npx cap init

? App name Stellar Wallet
? App Package ID (in Java package format, no dashes) com.wallet.stellar
? Which npm client would you like to use? npm

				
			

Initializing Capacitor project in

/Users/tylervanderhoeven/Desktop/Web/Clients/Stellar/stellar-demowallet in 1.91ms

Your Capacitor project is at launch readiness.

				
					Add platforms using "npx cap add":
npx cap add android
npx cap add ios
npx cap add electron

				
			

Setting Up Event Handling

On ./events/render.tsx file:

				
					import { h } from "@stencil/core";
export default function render() {
return [
<stellar-prompt prompter="{this.prompter}">,
this.account ? (
[
<div class="account-key">
<p>{this.account.publicKey}</p>
<button class="small" type="button" onclick="{(e)" ==""> this.copyAddress(e)}
>
Copy Address
</button>
<button class="small" type="button" onclick="{(e)" ==""> this.copySecret(e)}
>
Copy Secret
</button>
</div>,
]
) : (
<button type="button" onclick="{(e)" ==""> this.createAccount(e)}>
Create Account
</button>
),
this.error ? (
<span class="error">{JSON.stringify(this.error, null, 2)}</span>
) : null,
this.account ? (
<button type="button" onclick="{(e)" ==""> this.signOut(e)}>
Sign Out
</button>
) : null,
]
}
</stellar-prompt>

				
			

It's just a simple.tsx file that renders DOM based on a set of conditional values. A ternary operation switches between the Create account button and the standard account UI. If this.account is true, print the account's public key and several interaction buttons; if it is false, print the single Create Account button associated with the createAccount method. When an error occurs, print an error message followed by a Sign out button if there is an account to be signed out of.

Creating an Account

Everything up to this point has been a request to register an account, which generates a prompt modal to get a PIN. This passphrase is used by the sjcl.encrypt method to encrypt the secret key from keypair. random() function. Set this.account to the public key that encrypted the keystore cipher and store the cipher in base64 format in local storage using the set('keyStore') function. In addition, the cipher can be encoded as a QR code or a link that can be shared with other devices.

Copying the Address

Three further actions must be enabled after creating the account: copyAddress, copySecret, and signOut.

In ./methods/copyAddress.ts :

				
					import copy from "copy-to-clipboard";
export default async function copyAddress(e: Event) {
e.preventDefault();
copy(this.account.publicKey);
}
npm i -D copy-to-clipboard

				
			

Copying the Secret

In ./methods/copySecret.ts

				
					import sjcl from "@tinyanvil/sjcl";
import copy from "copy-to-clipboard";
import { handleError } from "@services/error";
export default async function copySecret(e: Event) {
try {
e.preventDefault();
const pincode = await this.setPrompt("Enter your keystore pincode");
if (!pincode) return;
this.error = null;
const secret = sjcl.decrypt(pincode, this.account.keystore);
copy(secret);
} catch (err) {
this.error = handleError(err);
}
}

				
			

Signing Out

And lastly, ./methods/signOut.ts

				
					import { remove } from "@services/storage";
import { handleError } from "@services/error";
export default async function signOut(e: Event) {
try {
e.preventDefault();
const confirmNuke = await this.setPrompt(
"Are you sure? This will nuke your account",
"Enter NUKE to confirm",
);
if (!confirm || !/nuke/gi.test(confirmNuke)) return;
this.error = null;
await remove("keyStore");
location.reload();
} catch (err) {
this.error = handleError(err);
}
}

				
			

Setting Prompts

The final method in wallet.ts file is ./methods/setPrompt.ts.

				
					export default function setPrompt(
message: string,
placeholder?: string,
options?: Array<any>,
): Promise<string> {
this.prompter = {
...this.prompter,
show: true,
message,
placeholder,
options,
};
return new Promise((resolve, reject) => {
this.prompter.resolve = resolve
this.prompter.reject = reject;
});
}

</string></any>

				
			

We Can Help You Create Stellar Blockchain Wallets According To Your Requirements

While some wallets focus on privacy, others are concerned with the best user experience. The best wallets are built by specialized blockchain experts who combine excellent UI/UX with privacy and security features. Working with a blockchain development company is a great way to build the best product that protects your users and supports multiple DApps.

We specialize in developing Stellar Blockchain solutions. It contributes to creating Stellar Wallet and the success of gamers, business owners, and investors by aiding these persons in launching a virtual metaverse space packed full of features and incorporating technology to a high degree of protection.

If you need assistance creating a Stellar wallet or integrating a Stellar wallet into an existing system, we're here to help. Connect with our Stellar developers and team to have your concept brought to life.

Let's build together on Stellar Blockchain

Conclusion

Stellar is gaining worldwide appeal due to its integrated order books, innovative consensus protocol, and compatibility with existing financial infrastructure. It offers low fees, quick transaction times, global access, universal asset exchange, and easy fiat entry and exit points within the network. By providing such advantageous features, stellar aspires to become the worldwide standard for money transfers. The crew is exerting its maximum effort to make it possible.

Next Article

Top 10 Use Cases of Stellar Blockchain

Other Related Services From Rejolut

Hire NFT
Developer

Solana Is A Webscale Blockchain That Provides Fast, Secure, Scalable Decentralized Apps And Marketplaces

Hire Solana
Developer

olana is growing fast as SOL becoming the blockchain of choice for smart contract

Hire Blockchain
Developer

There are several reasons why people develop blockchain projects, at least if these projects are not shitcoins

Why Rejolut?

1 Reduce Cost
RCW™ is the number one way to reduce superficial and bloated development costs.

We’ll work with you to develop a true ‘MVP’ (Minimum Viable Product). We will “cut the fat” and design a lean product that has only the critical features.
2 Define Product Strategy
Designing a successful product is a science and we help implement the same Product Design frameworks used by the most successful products in the world (Facebook, Instagram, Uber etc.)
3 Speed
In an industry where being first to market is critical, speed is essential. RCW™ is the fastest, most effective way to take an idea to development. RCW™ is choreographed to ensure we gather an in-depth understanding of your idea in the shortest time possible.
4 Limit Your Risk
Appsters RCW™ helps you identify problem areas in your concept and business model. We will identify your weaknesses so you can make an informed business decision about the best path for your product.

Our Clients

We as a blockchain development company take your success personally as we strongly believe in a philosophy that "Your success is our success and as you grow, we grow." We go the extra mile to deliver you the best product.

BlockApps

CoinDCX

Tata Communications

Malaysian airline

Hedera HashGraph

Houm

Xeniapp

Jazeera airline

EarthId

Hbar Price

EarthTile

MentorBox

TaskBar

Siki

The Purpose Company

Hashing Systems

TraxSmart

DispalyRide

Infilect

Verified Network

What Our Clients Say

Don't just take our words for it

I have worked with developers from many countries for over 20 years on some of the most high traffic websites and apps in the world. The team at rejolut.com are some of most professional, hard working and intelligent developers I have ever worked with rejolut.com have worked tirelessly and gone beyond the call of duty in order to have our dapps ready for Hedera Hashgraph open access. They are truly exceptional and I can’t recommend them enough.
Joel Bruce
Co-founder, hbarprice.com and earthtile.io
Rejolut is staying at the forefront of technology. From participating in, and winning, hackathons to showcase their ability to implement almost any piece of code. To contributing in open source software for anyone in the world to benefit from the increased functionality. They’ve shown they can do it all.
Pablo Peillard
Founder, Hashing Systems
Enjoyed working with the Rejolut team. Professional and with a sound understanding of smart contracts and blockchain. Easy to work with and I highly recommend the team for future projects. Kudos!
Zhang
Founder, 200eth
They have great problem-solving skills. The best part is they very well understand the business fundamentals and at the same time are apt with domain knowledge.
Suyash Katyayani
CTO, Purplle

Think Big, Act Now & Scale Fast

Speed up your blockchain adoption with our proven framework.

We are located at