-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integrate walletconnect #28
Changes from all commits
b9428a0
c25146b
346e061
56e0f33
6a92765
ecd21b7
e4f3b2e
2f12035
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { LitElement, html, css } from 'lit'; | ||
import { customElement, property } from 'lit/decorators.js'; | ||
import QRCode from 'qrcode'; | ||
|
||
@customElement('wallet-connect-modal') | ||
export class WalletconnectModalComponent extends LitElement { | ||
@property({ type: Boolean }) isOpen = false; | ||
@property({ type: String }) qrCodeData = ''; | ||
|
||
static styles = css` | ||
.modal { | ||
display: none; | ||
position: fixed; | ||
z-index: 1000; | ||
left: 0; | ||
top: 0; | ||
width: 100%; | ||
height: 100%; | ||
background-color: rgba(0, 0, 0, 0.4); | ||
} | ||
.modal-content { | ||
background-color: #fefefe; | ||
margin: 15% auto; | ||
padding: 20px; | ||
border: 1px solid #888; | ||
width: 80%; | ||
max-width: 500px; | ||
} | ||
.close { | ||
color: #aaa; | ||
float: right; | ||
font-size: 28px; | ||
font-weight: bold; | ||
cursor: pointer; | ||
} | ||
.close:hover, | ||
.close:focus { | ||
color: black; | ||
text-decoration: none; | ||
cursor: pointer; | ||
} | ||
`; | ||
|
||
render() { | ||
return html` | ||
<div class="modal" style="display: ${this.isOpen ? 'block' : 'none'}"> | ||
<div class="modal-content"> | ||
<span class="close" @click=${this.close}>×</span> | ||
<h4>Connect using xPortal on your phone</h4> | ||
<div id="qrContainer"></div> | ||
<button @click=${this.close}>Close</button> | ||
</div> | ||
</div> | ||
`; | ||
} | ||
|
||
async open(connectorUri: string) { | ||
this.isOpen = true; | ||
this.qrCodeData = await QRCode.toString(connectorUri, { type: 'svg' }); | ||
this.requestUpdate(); | ||
await this.updateComplete; | ||
const qrContainer = this.shadowRoot!.getElementById('qrContainer'); | ||
if (qrContainer) { | ||
qrContainer.innerHTML = this.qrCodeData; | ||
} | ||
} | ||
|
||
close() { | ||
this.isOpen = false; | ||
} | ||
} | ||
|
||
export function createModalFunctions() { | ||
const modalElement = document.createElement( | ||
'wallet-connect-modal' | ||
) as WalletconnectModalComponent; | ||
document.body.appendChild(modalElement); | ||
|
||
return { | ||
openModal: async (connectorUri: string) => { | ||
await modalElement.open(connectorUri); | ||
}, | ||
closeModal: () => { | ||
modalElement.close(); | ||
} | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { WalletConnectV2Provider } from '@multiversx/sdk-wallet-connect-provider'; | ||
import { IProvider } from 'core/providers/types/providerFactory.types'; | ||
import { createModalFunctions } from './components/WalletconnectModalComponent'; | ||
import { CurrentNetworkType } from 'types'; | ||
|
||
interface IWalletconnectProvider { | ||
openModal?: (connectorUri: string) => Promise<void>; | ||
closeModal?: () => void; | ||
onClientLogin?: () => Promise<void>; | ||
onClientLogout?: () => void; | ||
onClientEvent?: (event: any) => void; | ||
network: CurrentNetworkType; | ||
} | ||
|
||
export function createWalletconnectProvider( | ||
props: IWalletconnectProvider | ||
): IProvider { | ||
const modalFunctions = createModalFunctions(); | ||
const openModal = props.openModal ?? modalFunctions.openModal; | ||
const closeModal = props.closeModal ?? modalFunctions.closeModal; | ||
|
||
const provider = new WalletConnectV2Provider( | ||
prepareCallbacks(), | ||
props.network.chainId, | ||
props.network.walletConnectV2RelayAddress, | ||
String(props.network.walletConnectV2ProjectId) | ||
); | ||
|
||
const walletconnectLogin = provider.login; | ||
|
||
const createdProvider = provider as unknown as IProvider; | ||
|
||
function prepareCallbacks() { | ||
return { | ||
onClientLogin: async function () { | ||
closeModal(); | ||
const address = provider.getAddress(); | ||
console.log(`onClientLogin(), address: ${address}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. still need this log ? |
||
}, | ||
onClientLogout: function () { | ||
console.log('onClientLogout()'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe// TODO instead of logs ? |
||
}, | ||
onClientEvent: function (event: any) { | ||
console.log('onClientEvent()', event); | ||
} | ||
}; | ||
} | ||
|
||
createdProvider.login = async (options?: { | ||
callbackUrl?: string; | ||
token?: string; | ||
}): Promise<{ address: string; signature: string }> => { | ||
await provider.init(); | ||
const { uri, approval } = await provider.connect(); | ||
|
||
if (!uri) { | ||
throw 'URI not found'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this throw will be caught outside, where the login function is called since the throw inside the catch will be caught in the catch block here, in the function...is it intended? Do you think is better to have a uniform way to handle the error exceptions? |
||
} | ||
|
||
await openModal?.(uri); | ||
|
||
try { | ||
const account = await walletconnectLogin({ | ||
approval, | ||
token: options?.token | ||
}); | ||
|
||
const address = account?.address; | ||
const signature = account?.signature; | ||
|
||
if (!account) { | ||
throw new Error(`Connection Proposal Refused ${account}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this throw will be caught at the line:80 |
||
} | ||
|
||
return { | ||
address: address || '', | ||
signature: signature || '' | ||
}; | ||
} catch (err) { | ||
throw new Error(`Connection Proposal Refused, ${err}`); | ||
} | ||
}; | ||
|
||
return createdProvider; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it mandatory to pe statically defined here? Do you think it could be better to extract in a separate file ?