using System; using System.Collections; using System.Collections.Generic; using System.Drawing.Text; using UnityEngine; using UnityEngine.UI; using WalletConnectSharp.Unity; using WalletConnectSharp.Unity.Utils; using QRCoder; using QRCoder.Unity; [RequireComponent(typeof(Image))] public class WalletConnectQRImage : BindableMonoBehavior { public GameObject loader; /// /// The WalletConnect instance we'll work with to generate the QR code. /// public WalletConnect walletConnect; /// /// The image component we'll place the QR code texture into. /// [BindComponent] private Image _image; /// /// Flag to avoid adding additional OnConnectionStarted event handlers every time we disconnect & reconnect to the wallet (i.e. Disable/Enable this component). /// private bool registeredOnConnectionStartEvent = false; /// /// Unity OnEnable hook. /// void OnEnable() { if (walletConnect == null) { Debug.LogError("WalletConnectQRImage: No WalletConnect object given, QRImage will be disabled"); enabled = false; return; } // Only register the WalletConnectOnConnectionStarted handler once if (!registeredOnConnectionStartEvent) { registeredOnConnectionStartEvent = true; walletConnect.ConnectionStarted += WalletConnectOnConnectionStarted; ///////////////////////////////////////////////////////// /// WORKAROUND FOR: When OnEnable occurs after /// walletConnect.ConnectionStarted. if (walletConnect.Session != null) { WalletConnectOnConnectionStarted(null, null); } ///////////////////////////////////////////////////////// } } /// /// Event handler method to connect to a WalletConnect session and generate a QR code. /// /// Source of event /// Event arguments private void WalletConnectOnConnectionStarted(object sender, EventArgs e) { if (loader == null) { GenerateQrCode(); } else { walletConnect.StartCoroutine(ShowLoader()); } } private IEnumerator ShowLoader() { GenerateQrCode(); //hide the QRcode, show the loader, then wait a sec and then do the inverse _image.enabled = false; loader.SetActive(true); yield return new WaitForSeconds(1); _image.enabled = true; loader.SetActive(false); } private void GenerateQrCode() { // Grab the WC URL and generate a QR code for it. Note: The ECCLevel is the "Error Correction Code" level which // is basically how much checksum data to add to the code - the more checksum data the more likely the code can // be recovered on a slightly dodgy read. We'll go with the UnityWalletConnect default of Q(uality) as it's a // good compromise between readability and data storage capacity. // See: https://www.qrcode.com/en/about/version.html var url = walletConnect.Session.URI; //Debug.Log("Connecting to: " + url); QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q); UnityQRCode qrCode = new UnityQRCode(qrCodeData); // Copy the URL to the clipboard to allow for manual connection in wallet apps that support it GUIUtility.systemCopyBuffer = url; // Create the QR code as a Texture2D. Note: "pixelsPerModule" means the size of each black-or-white block in the // QR code image. For example, a size of 2 will give us a 138x138 image (too small!), while 20 will give us a // 1380x1380 image (too big!). Here we'll use a value of 10 which gives us a 690x690 pixel image. Texture2D qrCodeAsTexture2D = qrCode.GetGraphic(pixelsPerModule:10); // Change the filtering mode to point (i.e. nearest) rather than the default of linear - we want sharp edges on // the blocks, not blurry interpolated edges! qrCodeAsTexture2D.filterMode = FilterMode.Point; // Convert the texture into a sprite and assign it to our QR code image var qrCodeSprite = Sprite.Create(qrCodeAsTexture2D, new Rect(0, 0, qrCodeAsTexture2D.width, qrCodeAsTexture2D.height), new Vector2(0.5f, 0.5f), 100f); _image.sprite = qrCodeSprite; } }