UNPKG

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
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