angular-sol-wallets
Version:
<em> <p> news on 0.0.22 <ul> <li style="color:darkgreen">fix: use provider as static</li> </ul> </em> </p> <p> <br> This library was generated with <a href= "https://github.com/angular/angular-cli">Angular CLI</a> version 12.1.0. </p>
667 lines (656 loc) • 28.4 kB
JavaScript
import { __awaiter } from 'tslib';
import * as i0 from '@angular/core';
import { EventEmitter, Component, Injectable, NgModule } from '@angular/core';
import { Connection, clusterApiUrl, PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL } from '@solana/web3.js';
import * as bs58 from 'bs58';
import * as i1 from '@angular/common';
import { ReplaySubject } from 'rxjs';
import { BrowserModule } from '@angular/platform-browser';
class Wallet {
constructor() {
this.publicKey = null;
this.installed = false;
this.connected = false;
this.icon = "";
this.name = "";
}
connect() {
return __awaiter(this, void 0, void 0, function* () {
if (!Wallet.solanaConnection)
Wallet.solanaConnection = new Connection(clusterApiUrl(Wallet.cluster));
return this;
});
}
disconnect() {
return __awaiter(this, void 0, void 0, function* () {
if (Wallet.provider) {
Wallet.provider.disconnect();
this.connected = false;
}
return true;
});
}
signMessage(message) {
return __awaiter(this, void 0, void 0, function* () {
throw Error("No wallet.");
});
}
signTransfer(destinationPubkey, sols) {
return __awaiter(this, void 0, void 0, function* () {
throw Error("No wallet.");
});
}
signTransaction(transaction) {
return __awaiter(this, void 0, void 0, function* () {
//@ts-ignore
const nt = yield Wallet.provider.signTransaction(transaction);
return nt;
});
}
sendTransfer(transaction) {
return __awaiter(this, void 0, void 0, function* () {
return yield Wallet.solanaConnection.sendRawTransaction(transaction.serialize());
});
}
signAndSendTransfer(destinationPubkey, sols, signedCallBack) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
yield this.connect();
const transaction = yield this.signTransfer(destinationPubkey, sols);
if (signedCallBack) {
signedCallBack(transaction);
}
const signature = yield this.sendTransfer(transaction);
yield ((_a = Wallet.solanaConnection) === null || _a === void 0 ? void 0 : _a.confirmTransaction(signature, Wallet.commitment));
return signature;
});
}
sendTransaction(destinationPublickKey, sol) {
return __awaiter(this, void 0, void 0, function* () {
return null;
});
}
}
Wallet.solanaConnection = null;
Wallet.cluster = "devnet";
Wallet.commitment = "finalized";
Wallet.provider = null;
class PhantomWallet extends Wallet {
static create() {
return __awaiter(this, void 0, void 0, function* () {
const phantomWallet = new PhantomWallet();
//@ts-ignore
if (window.solana && window.solana.isPhantom) {
phantomWallet.installed = true;
localStorage.setItem('phantom', "installed");
}
else if (localStorage.getItem('phantom')) {
phantomWallet.installed = true;
}
return phantomWallet;
});
}
constructor() {
super();
this.icon = "https://gblobscdn.gitbook.com/spaces%2F-MVOiF6Zqit57q_hxJYp%2Favatar-1615495356537.png?alt=media";
this.name = "Phantom";
}
stakeConnection() {
//@ts-ignore
Wallet.provider = window.solana;
//@ts-ignore
this.publicKey = new PublicKey(Wallet.provider.publicKey);
this.connected = true;
}
connect() {
const _super = Object.create(null, {
connect: { get: () => super.connect }
});
return __awaiter(this, void 0, void 0, function* () {
yield _super.connect.call(this);
try {
//@ts-ignore
yield window.solana.connect({ onlyIfTrusted: true });
this.stakeConnection();
}
catch (e) {
}
//@ts-ignore
if (Wallet.provider !== null || Wallet.provider !== window.solana) {
//@ts-ignore
yield window.solana.connect();
this.stakeConnection();
}
return this;
});
}
disconnect() {
return __awaiter(this, void 0, void 0, function* () {
//@ts-ignore
yield window.solana.request({ method: "disconnect" });
return true;
});
}
signTransfer(destinationPubkey, sol) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const payerPubKey = this.publicKey;
const destinationPubKey = new PublicKey(destinationPubkey);
const transaction = new Transaction();
transaction.add(SystemProgram.transfer({
fromPubkey: payerPubKey,
toPubkey: destinationPubKey,
lamports: sol * LAMPORTS_PER_SOL
}));
const blockhash = yield ((_a = Wallet.solanaConnection) === null || _a === void 0 ? void 0 : _a.getRecentBlockhash());
transaction.recentBlockhash = blockhash.blockhash;
transaction.feePayer = payerPubKey;
//@ts-ignore
const nt = yield Wallet.provider.signTransaction(transaction);
return nt;
});
}
/**
* depreciated
* @param destinationPublickKey
* @param sol
* @returns
*/
sendTransaction(destinationPublickKey, sol) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
const payerPubKey = this.publicKey;
const destinationPubKey = new PublicKey(destinationPublickKey);
// const senderAccountInfo = await Wallet.solanaConnection?.getAccountInfo(payerPubKey!);
// const receiverAccountInfo = await Wallet.solanaConnection?.getAccountInfo(destinationPubKey);
const transaction = new Transaction();
transaction.add(SystemProgram.transfer({
fromPubkey: payerPubKey,
toPubkey: destinationPubKey,
lamports: sol * LAMPORTS_PER_SOL
}));
const blockhash = yield ((_a = Wallet.solanaConnection) === null || _a === void 0 ? void 0 : _a.getRecentBlockhash());
transaction.recentBlockhash = blockhash.blockhash;
transaction.feePayer = payerPubKey;
//@ts-ignore
const transactionSigned = yield Wallet.provider.signTransaction(transaction);
let signature = yield ((_b = Wallet.solanaConnection) === null || _b === void 0 ? void 0 : _b.sendRawTransaction(transactionSigned.serialize()));
let result = yield ((_c = Wallet.solanaConnection) === null || _c === void 0 ? void 0 : _c.confirmTransaction(signature, "singleGossip"));
return signature;
});
}
signMessage(message) {
return __awaiter(this, void 0, void 0, function* () {
const encodedMessage = new TextEncoder().encode(message);
//@ts-ignore
const signedMessage = yield Wallet.provider.request({
method: "signMessage",
params: {
message: encodedMessage
}
});
return signedMessage.signature;
});
}
}
class SolflareWallet extends Wallet {
constructor() {
var _a;
super();
this.icon = 'https://lh3.googleusercontent.com/uKZnhWrko3Chg3GkcqPZdj7RqfY0_toJ6s7JLWVMvBFb63pICmRYRsURzknIyuN0MeVlBSdTzNMm72zx0nh7-gJp1w=w128-h128-e365-rj-sc0x00ffffff';
this.name = "Solflare";
//@ts-ignore
if (window.solflare && ((_a = window.solflare) === null || _a === void 0 ? void 0 : _a.isSolflare)) {
this.installed = true;
localStorage.setItem('solflare', "installed");
}
else if (localStorage.getItem('solflare')) {
this.installed = true;
}
}
disconnect() {
return __awaiter(this, void 0, void 0, function* () {
//@ts-ignore
yield window.solflare.request({ method: "disconnect" });
return true;
});
}
static create() {
return __awaiter(this, void 0, void 0, function* () {
const solflareWallet = new SolflareWallet();
//@ts-ignore
if (window.solflare) {
solflareWallet.installed = true;
localStorage.setItem('solflare', "installed");
}
else if (localStorage.getItem('solflare')) {
solflareWallet.installed = true;
}
return solflareWallet;
});
}
stakeConnection() {
//@ts-ignore
Wallet.provider = window.solflare;
//@ts-ignore
this.publicKey = new PublicKey(Wallet.provider.publicKey);
this.connected = true;
}
connect() {
const _super = Object.create(null, {
connect: { get: () => super.connect }
});
return __awaiter(this, void 0, void 0, function* () {
yield _super.connect.call(this);
try {
//@ts-ignore
yield window.solflare.connect({ onlyIfTrusted: true });
this.stakeConnection();
}
catch (e) {
}
//@ts-ignore
if (Wallet.provider !== null || Wallet.provider !== window.solflare) {
//@ts-ignore
Wallet.provider = window.solflare;
//@ts-ignore
yield window.solflare.connect();
//@ts-ignore
if (window.solflare.publicKey) {
//@ts-ignore
Wallet.provider = window.solflare;
//@ts-ignore
this.publicKey = new PublicKey(Wallet.provider.publicKey);
}
}
return this;
});
}
signTransfer(destinationPubkey, sol) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const payerPubKey = this.publicKey;
const destinationPubKey = new PublicKey(destinationPubkey);
const transaction = new Transaction();
transaction.add(SystemProgram.transfer({
fromPubkey: payerPubKey,
toPubkey: destinationPubKey,
lamports: sol * LAMPORTS_PER_SOL
}));
const blockhash = yield ((_a = Wallet.solanaConnection) === null || _a === void 0 ? void 0 : _a.getRecentBlockhash());
transaction.recentBlockhash = blockhash.blockhash;
transaction.feePayer = payerPubKey;
//@ts-ignore
const nt = yield Wallet.provider.signTransaction(transaction);
return nt;
});
}
/**
* depreciated
* @param destinationPublickKey
* @param sol
* @returns
*/
sendTransaction(destinationPublickKey, sol) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
const payerPubKey = this.publicKey;
const destinationPubKey = new PublicKey(destinationPublickKey);
// const senderAccountInfo = await Wallet.solanaConnection?.getAccountInfo(payerPubKey!);
// const receiverAccountInfo = await Wallet.solanaConnection?.getAccountInfo(destinationPubKey);
const transaction = new Transaction();
transaction.add(SystemProgram.transfer({
fromPubkey: payerPubKey,
toPubkey: destinationPubKey,
lamports: sol * LAMPORTS_PER_SOL
}));
const blockhash = yield ((_a = Wallet.solanaConnection) === null || _a === void 0 ? void 0 : _a.getRecentBlockhash());
transaction.recentBlockhash = blockhash.blockhash;
transaction.feePayer = payerPubKey;
//@ts-ignore
const transactionSigned = yield Wallet.provider.signTransaction(transaction);
let signature = yield ((_b = Wallet.solanaConnection) === null || _b === void 0 ? void 0 : _b.sendRawTransaction(transactionSigned.serialize()));
let result = yield ((_c = Wallet.solanaConnection) === null || _c === void 0 ? void 0 : _c.confirmTransaction(signature, "singleGossip"));
return signature;
});
}
signMessage(message) {
return __awaiter(this, void 0, void 0, function* () {
const encodedMessage = new TextEncoder().encode(message);
//@ts-ignore
const signedMessage = yield Wallet.provider.signMessage(encodedMessage, "utf8");
const signature = bs58.encode(signedMessage.signature);
return signature;
});
}
}
class ModalComponent {
constructor(elRef) {
this.elRef = elRef;
this.wallets = [];
this.title = "Choose your wallet";
this.selectEvent = new EventEmitter();
this.quitEvent = new EventEmitter();
}
ngOnInit() {
//@ts-ignore
this.elRef.nativeElement.addEventListener('mousedown', ev => {
const container = document.querySelector("#wallet-container");
if (!(ev.clientX >= container.offsetLeft && ev.clientY <= container.offsetLeft + container.offsetWidth
&& ev.clientY >= container.offsetTop && ev.clientY <= container.offsetTop + container.offsetHeight)) {
this.quitEvent.emit();
}
});
}
select(i) {
this.selectEvent.emit(this.wallets[i]);
}
}
ModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ModalComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
ModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: ModalComponent, selector: "sw-modal", ngImport: i0, template: "<div id=\"wallet-container\" class=\"wallets-card\">\n <div *ngFor=\"let wallet of wallets ; let i = index\" class=\"wallets-row\" (click)=\"select(i)\">\n <img class=\"icon\" [src]=\"wallet.icon\" alt=\"\">\n <div class=\"name\">{{wallet.name}}</div>\n </div>\n</div>\n\n", styles: [":host{position:fixed;left:0px;top:0px;background-color:#00000020;width:100vw;height:100vh;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;z-index:999998}.wallets-card{min-width:200px;max-width:400px;background-color:#fff;border:1px solid gray;padding:1rem;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;border-radius:.25rem;grid-gap:.25rem;gap:.25rem;z-index:999999}.wallets-row{min-height:30px;width:100%;display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-between;border:1px solid gray;border-radius:.25rem;padding:.125rem;z-index:10000;cursor:pointer;transition:.5s}.wallets-row:hover{transform:scale(1.05)}.icon{max-height:3Opx;width:30px;height:30px}.name{flex:1;text-align:center}@media screen and (min-width: 1200px) and (min-height: 700px){.wallets-card{min-width:350px;max-width:500px;padding:1.5rem;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;border-radius:.5rem;grid-gap:.25rem;gap:.25rem;font-size:2rem}.wallets-title{font-size:2.5rem}.wallets-row{min-height:60px}.icon{max-height:60px;width:60px;height:60px}}\n"], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ModalComponent, decorators: [{
type: Component,
args: [{
selector: 'sw-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
class SolWalletsService {
constructor(componentFactoryResolver, appRef, injector) {
this.componentFactoryResolver = componentFactoryResolver;
this.appRef = appRef;
this.injector = injector;
this.walletsReady = new ReplaySubject();
this.autoConnect = false;
this.wallet = new ReplaySubject();
this.wallets = [];
this.enabledWallets = ["Phantom", "Solflare"];
this.selected = null;
this.classes = {};
this.wallet.subscribe(w => {
this.selected = w;
});
document.addEventListener('DOMContentLoaded', () => {
const buildWallets = () => __awaiter(this, void 0, void 0, function* () {
setTimeout(() => {
this.initWallets();
}, 0);
});
if (document.readyState === 'complete') {
buildWallets();
}
else {
function listener() {
window.removeEventListener('load', listener);
buildWallets();
}
window.addEventListener('load', listener);
}
});
}
initWallets() {
return __awaiter(this, void 0, void 0, function* () {
if (this.enabledWallets.filter(n => n === "Phantom").length >= 1) {
this.wallets.push(yield PhantomWallet.create());
}
if (this.enabledWallets.filter(n => n === "Solflare").length >= 1) {
this.wallets.push(yield SolflareWallet.create());
}
const connecteds = this.wallets.filter(w => w.connected);
if (connecteds.length >= 1 && this.autoConnect) {
if (localStorage.getItem("selected-wallet")) {
try {
const wallet = this.wallets.filter(w => w.name === localStorage.getItem("selected-wallet"))[0];
this.selectWallet(wallet);
wallet.connect();
}
catch (e) {
const wallet = connecteds[0];
this.selectWallet(wallet);
wallet.connect();
}
}
}
this.walletsReady.next(true);
});
}
selectWallet(wallet) {
this.wallet.next(wallet);
if (wallet) {
localStorage.setItem('selected-wallet', wallet.name);
}
else {
localStorage.removeItem('selected-wallet');
}
}
setCluster(cluster) {
Wallet.cluster = cluster;
}
setCommitment(commitment) {
Wallet.commitment = commitment;
}
setCustomClasses(classes) {
this.classes = classes;
}
setEnabledWallets(wallets) {
this.enabledWallets = wallets;
}
getPublicKey() {
if (this.selected) {
return this.selected.publicKey;
}
return null;
}
getProvider() {
return Wallet.provider;
}
/**
* Open the wallet(s) of client
* @returns a promise with the Wallet selected by the user
*/
connect() {
return new Promise((resolve, reject) => {
this.walletsReady.subscribe(ready => {
const wallets = this.wallets
.filter(w => w.installed)
.filter(w => this.enabledWallets.filter(e => e === w.name).length >= 1);
if (wallets.length > 1 && this.selected === null) {
const modalComponent = this.componentFactoryResolver
.resolveComponentFactory(ModalComponent)
.create(this.injector);
this.appRef.attachView(modalComponent.hostView);
const domElem = modalComponent.hostView
.rootNodes[0];
if (this.classes.background) {
domElem.classList.add(this.classes.background);
}
if (this.classes.card) {
const card = domElem.querySelector('#wallet-container');
card.className = this.classes.card;
}
if (this.classes.wallets) {
const card = domElem.querySelector('#wallet-container');
card.addEventListener('DOMNodeInserted', elem => {
//@ts-ignore
elem.target.className = this.classes.wallets;
});
}
modalComponent.instance.wallets = wallets;
modalComponent.instance.quitEvent.subscribe(() => {
this.appRef.detachView(modalComponent.hostView);
modalComponent.destroy();
});
modalComponent.instance.selectEvent.subscribe(selectedWallet => {
this.disconnect().finally(() => {
selectedWallet.connect().then(res => {
this.appRef.detachView(modalComponent.hostView);
modalComponent.destroy();
this.selectWallet(selectedWallet);
resolve(selectedWallet);
});
});
});
document.body.appendChild(domElem);
}
else if (wallets.length === 1 && this.selected === null) {
this.selectWallet(wallets[0]);
wallets[0].connect().then(w => {
resolve(this.selected);
});
}
else {
resolve(this.selected);
}
});
});
}
disconnect() {
return __awaiter(this, void 0, void 0, function* () {
if (this.selected) {
this.selected.disconnect();
yield this.selectWallet(null);
return true;
}
throw Error('No wallet selected.');
});
}
/**
* Sign a message on client-side
* @param message
* @returns a promise with the message signature.
*/
signMessage(message) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.selected) {
yield this.connect();
}
let signature = this.selected.signMessage(message);
;
return signature;
});
}
/**
* Create a client-side signature of a transfer transaction to send to your server.
* @param destinationPubkey the address of the receiver
* @param sols the ammount in SOLS to send from the client to the receiver
* @returns a promise with a buffer of the serialized transaction.
*/
signTransfer(destinationPubkey, sols) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.selected) {
yield this.connect();
}
return yield (yield this.selected.signTransfer(destinationPubkey, sols)).serialize();
});
}
/**
* Create a client-side signature of your custom solana transaction.
* @param transaction
* @returns signature
*/
signTransaction(transaction) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.selected) {
yield this.connect();
}
if (this.selected) {
return yield (yield this.selected.signTransaction(transaction)).serialize();
}
else {
throw Error("No wallet connected.");
}
});
}
/**
* Create, send an wait for confirmation of a transfer transaction
* Return a promise with a string signature.
* @param destinationPubkey the address of the receiver
* @param sols the ammount in SOLS to send from the client to the receiver
* @param signedByUser? optionnal: callbalck when user have signed the transaction in him wallet
*/
signAndSendTransfer(destinationPubkey, sols, signedByUser) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.selected) {
yield this.connect();
}
return this.selected.signAndSendTransfer(destinationPubkey, sols, signedByUser);
});
}
/**
* !!DE<PRECIATED FUNCTION!!
* @param destinationPubkey the address of the receiver
* @param sols the ammount in SOLS to send from the client to the receiver
* @returns
*/
sendTransaction(destinationPubkey, sols) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.selected) {
yield this.connect();
}
return this.selected.sendTransaction(destinationPubkey, sols);
});
}
}
SolWalletsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsService, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
SolWalletsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }]; } });
class SolWalletsComponent {
constructor() { }
ngOnInit() {
}
}
SolWalletsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
SolWalletsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: SolWalletsComponent, selector: "sw-sol-wallets", ngImport: i0, template: `
<p>
sol-wallets works!
</p>
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsComponent, decorators: [{
type: Component,
args: [{
selector: 'sw-sol-wallets',
template: `
<p>
sol-wallets works!
</p>
`,
styles: []
}]
}], ctorParameters: function () { return []; } });
class SolWalletsModule {
}
SolWalletsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
SolWalletsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsModule, declarations: [SolWalletsComponent,
ModalComponent], imports: [BrowserModule], exports: [SolWalletsComponent] });
SolWalletsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsModule, imports: [[
BrowserModule
]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SolWalletsModule, decorators: [{
type: NgModule,
args: [{
declarations: [
SolWalletsComponent,
ModalComponent
],
imports: [
BrowserModule
],
exports: [
SolWalletsComponent
]
}]
}] });
/*
* Public API Surface of sol-wallets
*/
/**
* Generated bundle index. Do not edit.
*/
export { SolWalletsComponent, SolWalletsModule, SolWalletsService, Wallet };
//# sourceMappingURL=angular-sol-wallets.js.map