### Start Local HTTP Server Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns This command starts a local HTTP server in the current directory, allowing the `index.html` and associated files to be served and viewed in a web browser. It requires `http-server` to be installed globally. ```Shell http-server . ``` -------------------------------- ### Start Local HTTP Server in Current Directory Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee Executes the globally installed `http-server` to serve files from the current directory. This command makes your web application accessible via a local HTTP address in your browser. ```bash http-server . ``` -------------------------------- ### Example Output of Running HTTP Server Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee This block shows the typical console output when the `http-server` starts successfully, listing the local IP addresses and port where the server is accessible. These addresses can be used to open the application in a web browser. ```text Starting up http-server, serving . Available on: http://127.0.0.1:8080 http://xxx.xxx.x.xx:8080 ``` -------------------------------- ### Detecting Plug Extension in Browser Console Source: https://docs.plugwallet.ooo/developer-guides/getting-started This JavaScript snippet checks for the presence of the `window.ic.plug` object, which indicates whether the Plug browser extension is installed and active. It's intended for quick testing in the browser developer console to confirm correct installation. ```JavaScript window.ic.plug && "Plug and play!" ``` -------------------------------- ### Request Connection to Plug Wallet Source: https://docs.plugwallet.ooo/developer-guides/getting-started This JavaScript snippet initiates a connection request to the Plug wallet using the `window.ic.plug.requestConnect()` method. It should be executed in the browser's developer console. Upon execution, a Plug notification window will pop up, prompting the user to allow or decline the connection. Access to this API is restricted to pages served over HTTP/HTTPS. ```JavaScript window.ic.plug.requestConnect() ``` -------------------------------- ### Initial HTML Scaffolding for Plugged Application Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This snippet provides the basic HTML structure for the 'Plugged' application, including the document title and commented placeholders for stylesheets, application logic, and the main application container. ```HTML Plugged ``` -------------------------------- ### Install Node.js HTTP Server Globally Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee This command installs the `http-server` package globally using npm, making it available from any directory in your terminal. It's a prerequisite for quickly serving local web projects. ```bash npm install --global http-server ``` -------------------------------- ### Launch Local HTTP Server Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Instructions to launch a local HTTP server using the `http-server` command-line tool. This command serves the current directory's files, making `index.html` and other assets accessible via a web browser. ```Shell http-server . ``` -------------------------------- ### Initialize DOM Selectors for Application Elements Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Defines an `els` object to store references to various DOM elements. This snippet shows the initial setup for accessing HTML elements like input fields and buttons using `document.querySelector`. ```JavaScript // Elements list const els = {}; // Assign elements to the elements list els.receiverPrincipalId = document.querySelector('#receiver-principal-id'); els.amount = document.querySelector('#amount'); els.btnConnect = document.querySelector('#btn-connect'); els.btnIsConnected = document.querySelector('#btn-is-connected'); els.btnRequestTransfer = document.querySelector('#btn-request-transfer'); ``` -------------------------------- ### Connect to Plug Wallet with Whitelist and Host Source: https://docs.plugwallet.ooo/developer-guides/connect-to-plug Example demonstrating how to connect to the Plug Wallet by passing optional parameters like `whitelist` (canister IDs) and `host` (network URL) to enable Plug Agent features for interacting with specific canisters. ```JavaScript (async () => { // Canister Ids const nnsCanisterId = 'qoctq-giaaa-aaaaa-aaaea-cai' // Whitelist const whitelist = [ nnsCanisterId, ]; // Host const host = "https://mainnet.dfinity.network"; // Make the request try { const publicKey = await window.ic.plug.requestConnect({ whitelist, host, timeout: 50000 }); console.log(`The connected user's public key is:`, publicKey); } catch (e) { console.log(e); } })(); ``` -------------------------------- ### Example: Initiating a Transfer with Plug `requestTransfer` Source: https://docs.plugwallet.ooo/developer-guides/balances-transactions Demonstrates how to use the `requestTransfer` method in JavaScript to send a specified amount to a target Principal ID, including an optional memo. The example shows an asynchronous call and logs the resulting block height. ```javascript (async () => { const params = { to: 'xxxxx-xxxxx-xxxxx-xxxxx', amount: 2_000_000, memo: '123451231231' }; const result = await window.ic.plug.requestTransfer(params); console.log(result); // { height: number } })(); ``` -------------------------------- ### Add Tailwind CSS to HTML Head Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This HTML snippet demonstrates how to include Tailwind CSS base and main stylesheets from a CDN into the `` section of an HTML document, alongside references to custom `main.css` and `app.js` files. ```HTML Plugged ``` -------------------------------- ### Linking External Stylesheets and JavaScript in HTML Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This HTML snippet demonstrates how to link external CSS (main.css) and JavaScript (app.js) files to the 'Plugged' application's index.html. It replaces the comment placeholders with actual and ``` -------------------------------- ### HTML Structure for Plugged Application UI Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This HTML snippet defines the basic layout of the 'Plugged' application's user interface. It includes a main application container, a title, placeholders for user input, button columns (wallet and token), and an output console area. Comments indicate where specific UI elements will be placed. ```HTML

Plugged

``` -------------------------------- ### Implement JavaScript Function to Write to Output Console Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Defines a utility function `outputWrite` that takes a text string as an argument. This function appends the text to the `els.output` textarea, ensuring each new message starts on a new line, and automatically scrolls the textarea to the bottom to show the latest content. ```javascript // Write to the output DOM element function outputWrite(text) { els.output.textContent += (els.output.textContent ? `\n` : '') + `> ${text}`; els.output.scrollTop = els.output.scrollHeight; } ``` -------------------------------- ### Implement Asynchronous Plug Wallet Connection in JavaScript Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This asynchronous JavaScript function, `onBtnConnect`, handles the logic for connecting to the Plug wallet. It calls `window.ic.plug.requestConnect()` to initiate the connection and logs the response, demonstrating a typical asynchronous interaction with the Plug API. ```JavaScript function main() { // the main implementation // function body omitted on purpose // ... } // On button press connect handler async function onBtnConnect() { const response = await window.ic?.plug?.requestConnect(); console.log("Response for Plug requestConnect() is ", response); } ``` -------------------------------- ### HTML Application Container with Tailwind CSS Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This HTML snippet defines the main application container (`#app`) and its internal structure, including a title, input fields for 'Send to address' and 'Amount', and various buttons for 'Wallet' and 'Tokens' functionalities. All elements are styled using Tailwind CSS utility classes for layout, typography, and spacing. ```HTML

Plugged

Wallet

Tokens

``` -------------------------------- ### Attach Click Event Listeners to Buttons (Declarative Style) Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Presents an alternative, more declarative approach to attaching click event listeners. It iterates through all elements in the `els` object, filters for elements that are buttons, and then adds a `click` listener to each, calling `onButtonPressHandler`. ```JavaScript function main () { // Assign elements to the elements list els.receiverPrincipalId = document.querySelector('#receiver-principal-id'); els.amount = document.querySelector('#amount'); els.btnConnect = document.querySelector('#btn-connect'); els.btnIsConnected = document.querySelector('#btn-is-connected'); els.btnRequestTransfer = document.querySelector('#btn-request-transfer'); // Initialise click listener for buttons (alternative style) Object .values(els) .filter((el) => el.nodeName === 'BUTTON') .forEach((el) => el.addEventListener( 'click', onButtonPressHandler ) ) } ``` -------------------------------- ### Display NNS Account Count in UI Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns This JavaScript snippet shows how to update a specific HTML element ('#accounts_count') with the 'accounts_count' value obtained from the NNS statistics and then reveal the UI container. It serves as a simple example for rendering fetched data in the user interface. ```JavaScript els.nnsStatsContainer.querySelector('#accounts_count').textContent = Number(stats.accounts_count); els.nnsStatsContainer.classList.remove('hidden'); ``` -------------------------------- ### Get User Principal ID with Plug Agent Source: https://docs.plugwallet.ooo/developer-guides/making-calls This example demonstrates how to connect to the Plug wallet and retrieve the user's principal ID using the Plug Agent. It involves setting up canister IDs for whitelisting, requesting a connection, and then calling the `getPrincipal()` method on the agent. ```JavaScript (async () => { // Canister Ids const nnsCanisterId = 'qoctq-giaaa-aaaaa-aaaea-cai' // Whitelist const whitelist = [ nnsCanisterId, ]; // Make the request const isConnected = await window.ic.plug.requestConnect({ whitelist, }); // Get the user principal id const principalId = await window.ic.plug.agent.getPrincipal(); console.log(`Plug's user principal Id is ${principalId}`); })(); ``` -------------------------------- ### Generate JavaScript Interface Factory from Candid DID File Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns Demonstrates how to use the `didc` command-line tool to bind a Candid `.did` file and generate a JavaScript interface factory file (`.did.js`). This generated file is crucial for creating actors that interact with canisters. ```Shell didc bind nns_ui.did -t js > nns_ui.did.js ``` -------------------------------- ### Log Plug Connection Status in Output Console Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Modifies the `onBtnConnect` asynchronous function to utilize the `outputWrite` utility. It logs the initiation of the `requestConnect` call and its subsequent response to the output console, providing real-time feedback on the Plug connection process. ```javascript async function onBtnConnect() { outputWrite('onBtnConnect() call'); const response = await window.ic?.plug?.requestConnect(); outputWrite(`onBtnConnect() call response ${response}`); } ``` -------------------------------- ### HTML Structure for Plug Authentication NNS App Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns This HTML file (`index.html`) sets up the basic structure for a Plug Authentication for NNS application. It includes a title, links to a stylesheet (`main.css`), and JavaScript files (`candid.js`, `app.js`). The body contains a logo, a container for NNS statistics (initially hidden), and a 'Connect with Plug' button. ```HTML Plug Authentication for NNS
``` -------------------------------- ### Connect Plug Wallet and Fetch NNS Statistics Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns This JavaScript function demonstrates the process of connecting to a Plug wallet, requesting user permission, initializing the Plug agent, creating an actor for the NNS UI canister, and then calling the 'get_stats' method to retrieve NNS statistics. It includes checks for connection and initialization failures. ```JavaScript async function onButtonPress(el) { const hasAllowed = await window.ic?.plug?.requestConnect({ whitelist, }); if (!hasAllowed) { els.btnTitle.textContent = "Plug wallet connection was refused"; return; } els.btnTitle.textContent = "Plug wallet is connected"; if (!window.ic.plug?.agent) { els.btnTitle.textContent = "Oops! Failed to initialise the Agent..."; return; } const NNSUiActor = await window.ic.plug?.createActor({ canisterId: nnsCanisterId, interfaceFactory: nnsUi, }); // Terminate on NNS Actor initialisation failure if (!NNSUiActor) { els.btnTitle.textContent = "Oops! Failed to initialise the NNS Actor..."; return; } const stats = await NNSUiActor?.get_stats(); console.log('NNS stats', stats); if (!stats) { els.btnTitle.textContent = "Oops! Failed to get the NNS Stats..."; return; } } ``` -------------------------------- ### Example: Burning XTC to Transfer Cycles with Plug `requestBurnXTC` Source: https://docs.plugwallet.ooo/developer-guides/balances-transactions Illustrates an asynchronous call to `requestBurnXTC` to transfer raw cycles (XTC) to a specified Canister ID. It's important to note that the amount is not in decimals and should be provided in the regular trillion cycles format. ```javascript (async () => { const params = { to: 'xxxxx-xxxxx-xxxxx-xxxxx', amount: 2_000_000 }; const result = await window.ic.plug.requestBurnXTC(params); console.log(result); })(); ``` -------------------------------- ### Check Plug Extension Availability in JavaScript Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This snippet demonstrates how to verify if the Plug extension is available in the browser's `window` object. If the extension is not detected, an alert message is displayed, and the function exits to prevent further execution of Plug-dependent code. ```JavaScript if (!window?.ic?.plug) { alert("Plug extension not detected!"); return; } ``` -------------------------------- ### JavaScript Logic for Plug Wallet Connection Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns This JavaScript file (`app.js`) handles the core logic for connecting with the Plug wallet. It initializes DOM elements, sets up an event listener for the 'Connect with Plug' button, and defines an asynchronous function `onButtonPress` to request connection to the Plug wallet and update the button text based on the connection status. ```JavaScript // Elements list const els = {}; // Initialises the application listeners and handlers function main() { els.btnTitle = document.querySelector('#btn-title') els.nnsStatsContainer = document.querySelector('#nns-stats-container'); els.button = document.querySelector('#button-connect'); els.button.addEventListener("click", onButtonPress); } // Button press handler async function onButtonPress(el) { const hasAllowed = await window.ic?.plug?.requestConnect(); if (!hasAllowed) { els.btnTitle.textContent = "Plug wallet connection was refused"; return; } els.btnTitle.textContent = "Plug wallet is connected"; } // Calls the Main function when the document is ready document.addEventListener("DOMContentLoaded", main); ``` -------------------------------- ### Request Plug Wallet Connection and Initialize Agent Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns Initiates a connection request to the Plug wallet, passing a whitelist of allowed canister IDs. It checks if the connection was successful and if the agent was initialized, updating UI text accordingly based on the connection status. ```JavaScript async function onButtonPress(el) { const isConnected = await window.ic?.plug?.requestConnect({ whitelist, }); if (!isConnected) { els.btnTitle.textContent = "Plug wallet connection was refused"; return; } els.btnTitle.textContent = "Plug wallet is connected"; if (!window.ic.plug?.agent) { els.btnTitle.textContent = "Oops! Failed to initialise the Agent..."; return; } } ``` -------------------------------- ### Implement Placeholder Button Press Handler Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Introduces a `onButtonPressHandler` function that serves as a temporary handler for button click events. It displays an alert message indicating which button was pressed based on its ID. ```JavaScript function main () { // Assign elements to the elements list els.receiverPrincipalId = document.querySelector('#receiver-principal-id'); els.amount = document.querySelector('#amount'); els.btnConnect = document.querySelector('#btn-connect'); els.btnIsConnected = document.querySelector('#btn-is-connected'); els.btnRequestTransfer = document.querySelector('#btn-request-transfer'); } function onButtonPressHandler(el) { const name = el.target.id; alert(`The button ${name} was pressed!`); } ``` -------------------------------- ### Define Canister ID and Whitelist for Plug Connection Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns Defines the NNS Canister ID and creates a whitelist array containing it. This whitelist is essential for the `requestConnect` method to specify allowed canisters for interaction with the Internet Computer. ```JavaScript // Canister Ids const nnsCanisterId = 'qoctq-giaaa-aaaaa-aaaea-cai' // Whitelist const whitelist = [ nnsCanisterId, ]; function main() { // Intentionally omitted // ... } async function onButtonPress(el) { // Intentionally omitted // ... } ``` -------------------------------- ### Styling for Plug Authentication NNS App Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns This CSS file (`main.css`) provides styling for the Plug Authentication for NNS application. It defines styles for the main application container, logo, buttons (including a rainbow gradient effect), and the NNS statistics display, ensuring a responsive and visually appealing interface. ```CSS #app { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; line-height: 1.4; } #logo { width: 80px; position: absolute; padding: 20px; top: 0; left: 0; } #btn-title { font-weight: 600; } .button-rainbow { border: none; background: linear-gradient(93.07deg, #FFD719 0.61%, #F754D4 33.98%, #1FD1EC 65.84%, #48FA6B 97.7%); padding: 2px; border-radius: 10px; cursor: pointer; transition: transform 0.3s; transform: scale(1) translate3d( 0, 0, 0) perspective(1px); } .button-rainbow:hover { transform: scale(1.04) translate3d( 0, 0, 0) perspective(1px); } .button-container { display: flex; flex-direction: row; align-items: center; background: white; padding: 5px 12px; border-radius: 10px; font-size: 16px; font-weight: 600; } .dark { background: #111827; color: white; } .plug-icon { margin-right: 9px; } #nns-stats-container { max-width: 400px; border: 1px solid #bbb; border-radius: 16px; box-sizing: border-box; padding: 0.4rem 1rem; margin-bottom: 20px; background: linear-gradient(39deg, rgba(34,34,40,1) 0%, rgba(34,34,51,1) 40%, rgba(34,34,67,1) 94%); color: #fff; } #nns-stats-container > div { display: flex; flex-flow: row; justify-content: space-between; } #nns-stats-container > div label { font-weight: bold; } #nns-stats-container > div:nth-child(2) label { color: #F754D4; } #nns-stats-container > div:nth-child(3) label { color: #1FD1EC; } #nns-stats-container > div:nth-child(4) label { color: #FFD719; } #nns-stats-container > div:last-child { margin-bottom: 20px; } .hidden { display: none; } ``` -------------------------------- ### Add HTML Structure for Output Console Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Adds a new HTML component to the application's structure, replacing a comment placeholder. This component provides a dedicated area (a textarea) to display output messages, styled with Tailwind CSS classes for a clean user interface. ```html
``` -------------------------------- ### Attach Click Event Listeners to Buttons (Imperative Style) Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Adds `click` event listeners to specific buttons (`btnConnect`, `btnIsConnected`, `btnRequestTransfer`) within the `main` function. This snippet demonstrates an imperative, one-by-one approach to attaching event handlers. ```JavaScript function main () { // Assign elements to the elements list els.receiverPrincipalId = document.querySelector('#receiver-principal-id'); els.amount = document.querySelector('#amount'); els.btnConnect = document.querySelector('#btn-connect'); els.btnIsConnected = document.querySelector('#btn-is-connected'); els.btnRequestTransfer = document.querySelector('#btn-request-transfer'); // Initialise click listener for buttons els.btnConnect.addEventListener('click', onButtonPressHandler); els.btnIsConnected.addEventListener('click', onButtonPressHandler); els.btnRequestTransfer.addEventListener('click', onButtonPressHandler); } ``` -------------------------------- ### Create Actor for Internet Computer Canister Interaction Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns Creates an Actor object using the Plug agent, which represents the target canister (NNS/UI) and allows interaction via its Candid interface. This requires the canister ID and an interface factory function. ```JavaScript const actor = await window.ic.plug.createActor({ canisterId: nnsCanisterId, interfaceFactory: nnsUi, }); ``` -------------------------------- ### Plug API: onExternalDisconnect Callback Source: https://docs.plugwallet.ooo/developer-guides/connect-to-plug Registers a callback function to be invoked when the connection to Plug is externally disconnected, for example, by the user directly in the wallet or due to a session timeout. ```APIDOC onExternalDisconnect(callback: () => void) ``` -------------------------------- ### Update JavaScript Button Handler for Plug Connection Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This updated `onButtonPressHandler` function integrates the `onBtnConnect` asynchronous call into the 'btn-connect' case of its switch statement. This modification replaces the previous placeholder alert, enabling the actual Plug wallet connection logic to be triggered upon button press. ```JavaScript // Button press handler function onButtonPressHandler(el) { const name = el.target.id; switch(name) { case 'btn-connect': onBtnConnect(); break; case 'btn-is-connected': alert("check the Plug connection state"); break; case 'btn-request-transfer': alert("request the Transfer"); break; default: alert('Button not found!'); }; } ``` -------------------------------- ### Rebuilding Plug Wallet Actors on Account Switches with `onConnectionUpdate` Source: https://docs.plugwallet.ooo/developer-guides/making-calls This snippet illustrates how to ensure actors are rebuilt when a user switches accounts by utilizing the `onConnectionUpdate` callback parameter of the `requestConnect` method. It provides an example of rebuilding a Sonic actor and fetching its swap information upon an account change. ```JavaScript (async () => { // Add the Sonic mainnet canister to whitelist const sonicCanisterId = '3xwpq-ziaaa-aaaah-qcn4a-cai'; const whitelist = [sonicCanisterId]; // Create an interface factory from a canister's IDL const sonicPartialInterfaceFactory = ({ IDL }) => { const TokenInfoExt = IDL.Record({ 'id' : IDL.Text, 'fee' : IDL.Nat, 'decimals' : IDL.Nat8, 'name' : IDL.Text, 'totalSupply' : IDL.Nat, 'symbol' : IDL.Text, }); const PairInfoExt = IDL.Record({ 'id' : IDL.Text, 'price0CumulativeLast' : IDL.Nat, 'creator' : IDL.Principal, 'reserve0' : IDL.Nat, 'reserve1' : IDL.Nat, 'lptoken' : IDL.Text, 'totalSupply' : IDL.Nat, 'token0' : IDL.Text, 'token1' : IDL.Text, 'price1CumulativeLast' : IDL.Nat, 'kLast' : IDL.Nat, 'blockTimestampLast' : IDL.Int, }); const SwapInfo = IDL.Record({ 'owner' : IDL.Principal, 'cycles' : IDL.Nat, 'tokens' : IDL.Vec(TokenInfoExt), 'pairs' : IDL.Vec(PairInfoExt), }); return IDL.Service({ 'getSwapInfo' : IDL.Func([], [SwapInfo], ['query']) }) } // requestConnect callback function const onConnectionUpdate = async () => { // rebuild actor and test by getting Sonic info const sonicActor = await window.ic.plug.createActor({ canisterId: sonicCanisterId, interfaceFactory: sonicPartialInterfaceFactory, }); // use our actors getSwapInfo method const swapInfo = await sonicActor.getSwapInfo(); console.log('Sonic Swap Info: ', swapInfo); } // Request a connection // Will fire onConnectionUpdate on account switch await window?.ic?.plug?.requestConnect({ whitelist, onConnectionUpdate, }); })() ``` -------------------------------- ### Secure IC Calls with Plug's createActor Method Source: https://docs.plugwallet.ooo/troubleshooting/app-trust-and-security This example demonstrates how an application can use Plug's IC Provider API to create an actor via the `createActor` method. By providing the IDL, Plug can decode arguments, ensuring that the user sees all transaction details in the approval pop-up without warnings, enhancing security and user trust. The snippet shows fetching a balance and initiating a transfer. ```javascript import XTCIdl from 'route/to/xtc.did.js'; const xtcCanisterId = 'aanaa-xaaaa-aaaah-aaeiq-cai'; // createActor approach (recommended) // Plug would be able to decode the arguments since it's receiving // the IDL. const secureXTCTransfer = async () => { const XTCActor = window?.ic?.plug?.createActor({canisterId: xtcCanisterId, interfaceFactory: XTCIdl}); const balance = await XTCActor.balance([]); console.log('My XTC Balance is ', balance, ' cycles'); // If the page were to lie, the user would realize by comparing to what it // is being prompted in the confirmation modal. console.log('Transfering 1000 cycles...'); await XTCActor.transfer({ to: 'paste-principalID-here', amount: BigInt(5000000000) }); console.log('Transfered 1000 cycles'); // You would never make it here cause the user would decline the sign }; ``` -------------------------------- ### Creating and Interacting with Internet Computer Canisters using Plug Wallet's `createActor` Source: https://docs.plugwallet.ooo/developer-guides/making-calls This asynchronous method creates an Actor to securely interact with an Internet Computer canister's interface. It requires prior Agent initialization via `requestConnect` with a whitelist. The example demonstrates creating an Actor for the NNS Canister UI using a partial interface factory and then calling its `get_stats()` method. ```JavaScript (async () => { // NNS Canister Id as an example const nnsCanisterId = 'qoctq-giaaa-aaaaa-aaaea-cai' const whitelist = [nnsCanisterId]; // Initialise Agent, expects no return value await window?.ic?.plug?.requestConnect({ whitelist, }); // A partial Interface factory // for the NNS Canister UI // Check the `plug authentication - nns` for more const nnsPartialInterfaceFactory = ({ IDL }) => { const BlockHeight = IDL.Nat64; const Stats = IDL.Record({ 'latest_transaction_block_height' : BlockHeight, 'seconds_since_last_ledger_sync' : IDL.Nat64, 'sub_accounts_count' : IDL.Nat64, 'hardware_wallet_accounts_count' : IDL.Nat64, 'accounts_count' : IDL.Nat64, 'earliest_transaction_block_height' : BlockHeight, 'transactions_count' : IDL.Nat64, 'block_height_synced_up_to' : IDL.Opt(IDL.Nat64), 'latest_transaction_timestamp_nanos' : IDL.Nat64, 'earliest_transaction_timestamp_nanos' : IDL.Nat64, }); return IDL.Service({ 'get_stats' : IDL.Func([], [Stats], ['query']), }); }; // Create an actor to interact with the NNS Canister // we pass the NNS Canister id and the interface factory const NNSUiActor = await window.ic.plug.createActor({ canisterId: nnsCanisterId, interfaceFactory: nnsPartialInterfaceFactory, }); // We can use any method described in the Candid (IDL) // for example the get_stats() // See https://github.com/dfinity/nns-dapp/blob/cd755b8/canisters/nns_ui/nns_ui.did const stats = await NNSUiActor.get_stats(); console.log('NNS stats', stats); })() ``` -------------------------------- ### Encapsulate DOM Selectors in main Function and Defer Execution Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Wraps the DOM element selection and assignment within a `main` function. This function is then called only after the DOM is fully loaded using `DOMContentLoaded` event, ensuring all elements are available before selection to prevent 'elements not found' errors. ```JavaScript // Elements list const els = {}; // Initialises the application listeners and handlers function main() { // Assign elements to the elements list els.receiverPrincipalId = document.querySelector('#receiver-principal-id'); els.amount = document.querySelector('#amount'); els.btnConnect = document.querySelector('#btn-connect'); els.btnIsConnected = document.querySelector('#btn-is-connected'); els.btnRequestTransfer = document.querySelector('#btn-request-transfer'); } // Calls the Main function when the document is ready document.addEventListener("DOMContentLoaded", main); ``` -------------------------------- ### Select Output DOM Element in JavaScript Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged Adds a new selector to the `app.js` file to retrieve the HTML textarea element designated for output. This line assigns the DOM element with the ID 'output' to `els.output`, making it accessible for JavaScript manipulation. ```javascript els.output = document.querySelector('#output'); ``` -------------------------------- ### Generate TypeScript Type Definitions from Candid DID File Source: https://docs.plugwallet.ooo/build-an-app-examples/plug-auth-nns Shows how to use the `didc` command-line tool to generate TypeScript type definitions (`.did.d.ts`) from a Candid `.did` file. These type definitions provide type safety and auto-completion for canister interfaces in TypeScript projects. ```Shell didc bind nns_ui.did -t ts > nns_ui.did.d.ts ``` -------------------------------- ### Implement JavaScript Button Event Handler with Switch Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This JavaScript function `onButtonPressHandler` uses a switch statement to manage different button click events based on their IDs. It currently includes placeholder alerts for 'connect', 'is-connected', and 'request-transfer' actions, which are intended to be replaced with actual Plug API calls. ```JavaScript // Button press handler function onButtonPressHandler(el) { const name = el.target.id; switch(name) { case 'btn-connect': alert("handle the Plug connection"); break; case 'btn-is-connected': alert("check the Plug connection state"); break; case 'btn-request-transfer': alert("request the Transfer"); break; default: alert('Button not found!'); }; } ``` -------------------------------- ### Custom CSS for Button Styling Source: https://docs.plugwallet.ooo/build-an-app-examples/plugged This CSS snippet defines a custom `.btn` class to apply unique styling to buttons, including a vibrant linear gradient background, rounded borders, text shadow, and custom padding. It also includes a hover effect that slightly scales the button and reduces its opacity, providing a visually distinct appearance that complements Tailwind CSS. ```CSS .btn { border: none; font-style: normal; font-weight: bold; font-size: 16px; line-height: 24px; background: linear-gradient(94.95deg, #FFE701 -1.41%, #FA51D3 34.12%, #10D9ED 70.19%, #52FF53 101.95%); border-radius: 10px; color: #fff; text-shadow: 0px 2px 3px rgb(0 0 0 / 16%); padding: 6px 32px; cursor: pointer; transition: opacity 0.3s ease-in, transform 0.3s ease-in-out; transform: scale(1); } .btn:hover { opacity: 0.94; transform: scale(1.02); } ``` -------------------------------- ### Incorrect Canister Call with Plug Wallet (Agent Approach) Source: https://docs.plugwallet.ooo/troubleshooting/app-trust-and-security This example demonstrates an incorrect method of making a canister call using Plug Wallet. It directly uses the 'window?.ic?.plug?.agent' to create an actor, bypassing Plug's 'createActor' method. This prevents Plug from decoding the arguments of the update call, leading to a warning message for the user as the transaction details (e.g., transfer amount) cannot be displayed in the confirmation modal. ```JavaScript import XTCIdl from 'route/to/xtc.did.js'; const xtcCanisterId = 'aanaa-xaaaa-aaaah-aaeiq-cai'; // Agent approach (not recommended) // Plug would not be able to decode the arguments since the IDL // is not available to the provider and is used locally by the app. const insecureXTCTransfer = async () => { const agent = window?.ic?.plug?.agent; const XTCActor = Actor.createActor(XTCIdl, { canisterId: xtcCanisterId }); const balance = await XTCActor.balance([]); console.log('My XTC Balance is ', balance, ' cycles'); // This is a lie! The user would not be able to see how much it's transferring in the confirmation modal. console.log('Transfering 1000 cycles...'); await XTCActor.transfer({ to: 'paste-principalID-here', amount: BigInt(500000000000), }); console.log('Transfered 1000 cycles'); }; ``` -------------------------------- ### Create Basic HTML Page Structure Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee Provides the initial HTML boilerplate for the 'Buy me a coffee' application, including placeholders for stylesheet and JavaScript links, and the main application container. ```html Buy me a coffee ``` -------------------------------- ### Connect to Plug Wallet Source: https://docs.plugwallet.ooo/developer-guides/connect-to-plug Demonstrates how to initiate a connection request to the Plug Wallet, showing a pop-up to the user. Resolves with the connected user's public key upon approval or throws an error if declined. ```JavaScript (async () => { try { const publicKey = await window.ic.plug.requestConnect(); console.log(`The connected user's public key is:`, publicKey); } catch (e) { console.log(e); } })(); ``` -------------------------------- ### Add Call-to-Action Button to HTML Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee Updates the `index.html` file to embed a `div` with ID 'app' and a 'Buy me a coffee' button inside, replacing the placeholder comment for the application container. ```html Buy me a coffee
``` -------------------------------- ### Initialize JavaScript Event Listeners for Button Click Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee This JavaScript code sets up event listeners for a 'Buy me a coffee' button. It initializes the application when the DOM is ready, attaches a click handler to the button, and displays an alert when the button is pressed. ```JavaScript // Initialises the application listeners and handlers function main() { const button = document.querySelector('#buy-me-coffee'); button.addEventListener("click", onButtonPress); } // Button press handler function onButtonPress() { alert("Buy me a coffee button was pressed!") } // Calls the Main function when the document is ready document.addEventListener("DOMContentLoaded", main); ``` -------------------------------- ### Link External CSS Stylesheet in HTML Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee Modifies the `index.html` to include a `` tag in the `` section, referencing an external `main.css` file for application styling. ```html Buy me a coffee
``` -------------------------------- ### Plug API: requestConnect Method Source: https://docs.plugwallet.ooo/developer-guides/connect-to-plug Initiates a connection request from the application to the Plug wallet, allowing the app to interact with the user's wallet. ```APIDOC requestConnect ``` -------------------------------- ### Connect to Plug Wallet Extension Asynchronously Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee This asynchronous JavaScript function checks for the presence of the Plug wallet extension and attempts to connect to it. It uses `window.ic.plug.requestConnect()` to prompt the user for connection, logging the success or refusal of the connection attempt. ```JavaScript async function onButtonPress() { const hasAllowed = await window.ic.plug.requestConnect(); if (hasAllowed) { console.log('Plug wallet is connected'); } else { console.log('Plug wallet connection was refused') } } ``` -------------------------------- ### Initialize Plug Mobile Provider for dApp Source: https://docs.plugwallet.ooo/developer-guides/mobile-auth This code initializes the `PlugMobileProvider` when the dApp is detected as running in a mobile environment. It requires a WalletConnect Project ID for secure communication and allows for debug logging. The `initialize()` method establishes the necessary connections. ```TypeScript if (isMobile) { const provider = new PlugMobileProvider({ debug: true, // If you want to see debug logs in console walletConnectProjectId: '', // Project ID from WalletConnect console window: window, }) provider.initialize().catch(console.log) } ``` -------------------------------- ### Link External JavaScript File in HTML Source: https://docs.plugwallet.ooo/build-an-app-examples/buy-me-a-coffee This HTML snippet demonstrates how to link an external JavaScript file, `app.js`, to an HTML document. It includes a basic page structure with a title, a stylesheet link, and a button element, ensuring the JavaScript functionality is loaded and available. ```HTML Buy me a coffee
``` -------------------------------- ### Persist Plug Wallet Connection Source: https://docs.plugwallet.ooo/developer-guides/connect-to-plug Demonstrates a basic check to ensure the Plug Wallet connection persists across user navigation. If not connected, it attempts to re-establish the connection with the previously used whitelist and host. ```JavaScript const connected = await window.ic.plug.isConnected(); if (!connected) await window.ic.plug.requestConnect({ whitelist, host }); ``` -------------------------------- ### Access Plug Agent Object Source: https://docs.plugwallet.ooo/developer-guides/making-calls This snippet shows how the Plug Agent instance is assigned to the window Plug object, making it accessible for further interactions with the Internet Computer. ```JavaScript window.ic.plug.agent ``` -------------------------------- ### Plug Agent Integration Parameters for requestConnect Source: https://docs.plugwallet.ooo/developer-guides/connect-to-plug Defines the optional parameters that can be passed to `requestConnect` to integrate Plug's Agent features, including whitelisting canister IDs and specifying a host URL for authentication and signing requests. ```APIDOC Object { whitelist?: ['canister-id'], host?: 'https://network-address', timeout: 50000 } ```