### Start Development Server with Bun Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Starts the development server, which includes auto-recompilation of the SDK. This allows for live testing of changes in a local demo app. ```bash bun start ``` -------------------------------- ### Install Dependencies with Bun Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Installs all necessary project dependencies using the Bun package manager. This is a prerequisite for running the development server and building the SDK. ```bash bun install ``` -------------------------------- ### Install and Import Loop SDK (Bash, JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Instructions for installing the Loop SDK using npm and importing it into your JavaScript project. It also shows how to use unpkg for direct file inclusion without a build process. ```bash bun add @fivenorth/loop-sdk ``` ```javascript import { loop } from '@fivenorth/loop-sdk'; // Or for direct inclusion: import { loop } from 'https://unpkg.com/@fivenorth/loop-sdk@0.1.1/dist'; ``` -------------------------------- ### JavaScript: Loop SDK Full Integration Example Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt This JavaScript example demonstrates the complete integration workflow for the Loop SDK. It covers initializing the SDK with application details and network settings, managing connection/disconnection events, fetching user holdings and active contracts, and submitting a token transfer transaction. Dependencies include the '@fivenorth/loop-sdk' package. It outputs connection status, holdings, contract counts, and transaction results to the console. ```javascript import { loop } from '@fivenorth/loop-sdk'; class LoopDApp { constructor() { this.provider = null; this.init(); } init() { loop.init({ appName: 'My Canton dApp', network: 'mainnet', options: { openMode: 'popup', redirectUrl: 'https://myapp.com/dashboard', }, onAccept: (provider) => { this.provider = provider; this.onConnected(); }, onReject: () => { this.onDisconnected(); }, }); } connect() { loop.connect(); } async onConnected() { console.log('Connected:', this.provider.party_id); // Fetch initial data try { const holdings = await this.provider.getHolding(); this.displayHoldings(holdings); const contracts = await this.provider.getActiveContracts({ templateId: '#splice-amulet:Splice.Amulet:Amulet' }); this.displayContracts(contracts); } catch (error) { console.error('Error loading data:', error); } } onDisconnected() { this.provider = null; console.log('Disconnected from Loop wallet'); } displayHoldings(holdings) { holdings.forEach(h => { const total = parseFloat(h.total_unlocked_coin) + parseFloat(h.total_locked_coin); console.log(`${h.symbol}: ${total.toFixed(h.decimals)}`); }); } displayContracts(contracts) { console.log(`Found ${contracts.length} contracts`); } async transfer(recipient, amount) { if (!this.provider) { throw new Error('Not connected'); } const command = { commands: [{ ExerciseCommand: { templateId: '#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory', contractId: 'contract-id-here', choice: 'TransferFactory_Transfer', choiceArgument: { expectedAdmin: 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a', transfer: { sender: this.provider.party_id, receiver: recipient, amount: amount.toString(), instrumentId: { admin: 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a', id: 'Amulet', }, requestedAt: new Date().toISOString(), executeBefore: new Date(Date.now() + 86400000).toISOString(), lock: null, inputHoldingCids: [], meta: { values: {} }, }, extraArgs: { context: { values: {} }, meta: { values: {} } }, } } }], disclosedContracts: [], }; return await this.provider.submitTransaction(command); } } // Initialize app const app = new LoopDApp(); // Connect when button clicked document.getElementById('connect').onclick = () => app.connect(); ``` -------------------------------- ### Initialize Loop SDK with Custom URLs (JavaScript) Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Configures the Loop SDK with custom wallet and API endpoint URLs, suitable for development or self-hosted setups. It initializes the application name, network, and defines callbacks for connection acceptance and rejection. ```javascript loop.init({ appName: 'Development dApp', network: 'local', walletUrl: 'http://localhost:3000', apiUrl: 'http://localhost:8080', options: { openMode: 'tab', }, onAccept: (provider) => { console.log('Connected to local development wallet'); console.log('API endpoint:', provider.connection.apiUrl); console.log('Wallet URL:', provider.connection.walletUrl); }, onReject: () => { console.log('Connection rejected'); }, }); loop.connect(); ``` -------------------------------- ### Get Holdings using Loop SDK Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Retrieves the user's current holdings from the ledger using the Loop SDK. This function is called when the 'Get Holdings' button is clicked and displays the retrieved holdings. Requires a connected provider. ```javascript const handleGetHolding = async () => { if (!provider) { alert('Please connect first.'); return; } setIsLoading(true); setHoldings([]); try { // Assuming a method like 'getHoldings' exists on the provider // const userHoldings = await provider.getHoldings(); // setHoldings(userHoldings); // Simulating data for demonstration: setHoldings([ { symbol: 'XYZ', total_unlocked_coin: '100.50', total_locked_coin: '20.25', decimals: 2, instrument_id: { id: 'inst_xyz' } }, { symbol: 'ABC', total_unlocked_coin: '50.00', total_locked_coin: '0.00', decimals: 2, instrument_id: { id: 'inst_abc' } } ]); } catch (error) { console.error('Failed to get holdings:', error); alert('Failed to get holdings. See console.'); } finally { setIsLoading(false); } }; ``` -------------------------------- ### Get Active Contracts by Template or Interface ID (JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Queries the DAML ledger for active contracts based on either a `templateId` or an `interfaceId`. This allows dApps to fetch specific types of contracts relevant to their functionality. ```javascript const contracts = await provider.getActiveContracts({ templateId: '#splice-amulet:Splice.Amulet:Amulet' }); console.log(contracts); const contracts = await provider.getActiveContracts({ interfaceId: '#splice-api-token-holding-v1:Splice.Api.Token.HoldingV1:Holding' }); console.log(contracts); ``` -------------------------------- ### Get User Token Holdings (JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Retrieves the current token holdings of the connected user via the provider object. This method is asynchronous and returns a promise that resolves with the holdings data. ```javascript const holdings = await provider.getHolding(); console.log(holdings); ``` -------------------------------- ### Get User Token Holdings (JavaScript) Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Retrieves all token holdings for a connected user account, including both locked and unlocked balances. This function assumes a provider object is available from the `onAccept` callback during SDK initialization. It iterates through the holdings to display details such as symbol, balance, organization, instrument ID, and image. ```javascript // Assumes provider is available from onAccept callback async function fetchAndDisplayHoldings(provider) { try { const holdings = await provider.getHolding(); holdings.forEach(holding => { const totalBalance = parseFloat(holding.total_unlocked_coin) + parseFloat(holding.total_locked_coin); console.log(`${holding.symbol}: ${totalBalance.toFixed(holding.decimals)}`); console.log(` Unlocked: ${holding.total_unlocked_coin}`); console.log(` Locked: ${holding.total_locked_coin}`); console.log(` Organization: ${holding.org_name}`); console.log(` Instrument: ${holding.instrument_id.admin}::${holding.instrument_id.id}`); console.log(` Image: ${holding.image}`); }); return holdings; } catch (error) { console.error('Error fetching holdings:', error); throw error; } } // Usage fetchAndDisplayHoldings(window.loopProvider); ``` -------------------------------- ### Initialize Loop SDK Configuration (JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Demonstrates how to initialize the Loop SDK with essential configuration parameters such as application name, network, and connection options. Includes callbacks for connection acceptance and rejection. ```javascript loop.init({ appName: 'My Awesome dApp', network: 'local', // or 'devnet', 'mainnet' options: { openMode: 'popup', // 'popup' (default) or 'tab' redirectUrl: 'https://myapp.com/after-connect', // optional redirect after approval }, onAccept: (provider) => { console.log('Connected!', provider); // You can now use the provider to interact with the wallet }, onReject: () => { console.log('Connection rejected by user.'); }, }); ``` -------------------------------- ### Build and Publish Package with Bun Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Builds the SDK package and publishes it to NPM. These commands are used for releasing new versions of the SDK. ```bash bun run build bun publish ``` -------------------------------- ### Initialize and Connect to Loop SDK Provider Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Initializes the Loop SDK with application details and connection options, then establishes a connection to the Loop network. It handles connection acceptance and rejection, setting up the provider and account information upon successful connection. Dependencies include 'preact' for UI and 'preact/hooks' for state management. ```javascript import { h, render } from 'https://esm.sh/preact'; import { useState, useEffect } from 'https://esm.sh/preact/hooks'; import htm from 'https://esm.sh/htm'; import { loop } from './dist/index.js'; const html = htm.bind(h); function App() { const [account, setAccount] = useState(null); const [provider, setProvider] = useState(null); // ... other states useEffect(() => { loop.init({ appName: 'My Test DApp', network: 'local', options: { openMode: 'popup', // 'popup' (default) or 'tab' redirectUrl: 'https://myapp.com/after-connect', // optional redirect after approval }, onAccept: (prov) => { setProvider(prov); console.log('Provider:', prov); setAccount({ partyId: prov.party_id, publicKey: prov.public_key }); }, onReject: () => { alert('Connection Rejected!'); setAccount(null); setProvider(null); // ... reset other states }, }); }, []); const handleConnect = () => { loop.connect(); }; // ... rest of the component return (
{!account ? ( ) : (

Connected as: {account.partyId}

)} {/* ... other UI elements */}
); } render(, document.getElementById('app')); ``` -------------------------------- ### Initialize Loop SDK (JavaScript) Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Initializes the Loop SDK with application details, network configuration, and event handlers for connection success or failure. It requires the appName, network, and optional options like openMode and redirectUrl. The onAccept callback receives a provider object upon successful connection, while onReject handles connection rejections. ```javascript import { loop } from '@fivenorth/loop-sdk'; loop.init({ appName: 'My Awesome dApp', network: 'devnet', // 'local', 'devnet', 'testnet', 'mainnet' options: { openMode: 'popup', // 'popup' (default) or 'tab' redirectUrl: 'https://myapp.com/after-connect', // optional }, onAccept: (provider) => { console.log('Connected successfully!'); console.log('Party ID:', provider.party_id); console.log('Public Key:', provider.public_key); console.log('Email:', provider.email); // Store provider for later use window.loopProvider = provider; }, onReject: () => { console.error('User rejected the connection'); // Handle rejection - show error message to user }, }); // Initiate connection - shows QR code modal loop.connect(); ``` -------------------------------- ### Connect to Loop Wallet (JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Initiates the connection process to the Loop wallet by calling the `loop.connect()` method. This action typically opens a modal with a QR code for the user to scan. ```javascript loop.connect(); ``` -------------------------------- ### Sign Messages with Loop SDK Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Demonstrates how to sign arbitrary messages using the Loop SDK. It takes a raw message, initiates the signing process via the connected provider, and stores the resulting signature. This is essential for proving ownership or authorizing actions off-chain. Dependencies include the Loop SDK provider. ```javascript const [rawMessage, setRawMessage] = useState('Hello, Loop!'); const [signature, setSignature] = useState(null); const [isSigning, setIsSigning] = useState(false); // ... inside the component or a handler function const handleSignMessage = async () => { if (!provider || !rawMessage) { alert('Please connect and enter a message to sign.'); return; } setIsSigning(true); try { const signedMessage = await provider.signMessage(rawMessage); console.log('Signed message:', signedMessage); setSignature(signedMessage); alert('Message signed successfully! Check console.'); } catch (error) { console.error('Failed to sign message:', error); alert('Failed to sign message. See console.'); } finally { setIsSigning(false); } }; // UI element to trigger signing: // //

Signature: {signature}

``` -------------------------------- ### Connect to Loop Wallet (JavaScript) Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Establishes a connection to the Loop wallet, either by displaying a QR code for mobile scanning or opening the wallet in a popup/tab for desktop users. This function should be called after SDK initialization. It handles session persistence using sessionStorage and includes logic to fetch user data upon successful connection. ```javascript import { loop } from '@fivenorth/loop-sdk'; // Initialize first loop.init({ appName: 'Token Transfer App', network: 'mainnet', options: { openMode: 'popup', }, onAccept: async (provider) => { // Auto-resume on page reload sessionStorage.setItem('connected', 'true'); // Immediately fetch user data try { const holdings = await provider.getHolding(); console.log('User holdings:', holdings); } catch (error) { console.error('Failed to fetch holdings:', error); } }, onReject: () => { sessionStorage.removeItem('connected'); alert('Connection rejected. Please try again.'); }, }); // Connect when user clicks button document.getElementById('connectBtn').addEventListener('click', () => { loop.connect(); }); // SDK automatically handles session persistence via localStorage // Reconnection happens automatically on page reload ``` -------------------------------- ### Connect to Provider (Loop SDK) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Initiates the connection process to the Loop SDK provider. This function is typically triggered by a user action, such as clicking a 'Connect' button. It handles the initial connection flow. ```javascript const handleConnect = async () => { // Assuming provider is available globally or imported elsewhere // For demonstration, we'll simulate connection logic // In a real app, this would involve calling a method on the Loop SDK instance alert('Connecting...'); // Simulate successful connection // setProvider({ submitTransaction: () => {}, signMessage: () => {}, ... }); // setAccount({ partyId: 'party_123', publicKey: 'pk_abc' }); }; ``` -------------------------------- ### Submit a DAML Transaction (JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Constructs and submits a DAML transaction to the ledger. This involves defining the command object, including the exercise command with relevant details such as template ID, contract ID, choice, and arguments. Error handling for transaction submission is included. ```javascript const damlCommand = { commands: [{ ExerciseCommand: { templateId: "#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory", contractId: 'your-contract-id', // The contract ID to exercise the choice on choice: 'TransferFactory_Transfer', choiceArgument: { // ... your choice arguments } } }], // ... other command properties }; try { const result = await provider.submitTransaction(damlCommand); console.log('Transaction successful:', result); } catch (error) { console.error('Transaction failed:', error); } ``` -------------------------------- ### Sign Message with Loop SDK Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Enables users to sign arbitrary messages using the connected Loop SDK provider. It manages the signing process state and displays the resulting signature or any errors encountered. Requires a connected provider and a message to sign. ```javascript const handleSignMessage = async () => { if (!provider) { alert('Please connect first.'); return; } setIsSigning(true); setSignature(null); try { const result = await provider.signMessage(rawMessage); setSignature(result); } catch (error) { console.error('Failed to sign message:', error); alert('Failed to sign message. See console.'); setSignature({ error: error.message }); } finally { setIsSigning(false); } }; ``` -------------------------------- ### Construct and Submit DAML Transaction Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Defines a function to create a DAML command for a token transfer and prepares it for submission. It dynamically sets the `partyId` based on the connected account and generates timestamps for execution. This function is crucial for initiating on-chain operations. Dependencies include the Loop SDK and standard JavaScript Date objects. ```javascript const getDamlCommandTemplate = (partyId = '') => ({ commands: [ { ExerciseCommand: { templateId: '#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory', contractId: '009f00e5bf00640118d849080aaf22bc963a8458d322585cebf1119ca11122065b775fb8a4199904ed32fa9277fd9c0e82bb82319a7151249df124182072381', choice: 'TransferFactory_Transfer', choiceArgument: { expectedAdmin: 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a', transfer: { sender: partyId, receiver: '510ae534b026134d27e23ee14ac83be3::1220e21e937baf58245ad64e5e4a903a6b6c46e86c6d12dc0d7408be746fb804b56d', amount: '1.5', instrumentId: { admin: 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a', id: 'Amulet', }, requestedAt: new Date().toISOString(), executeBefore: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), lock: null, meta: { values: {}, }, inputHoldingCids: ['list-of-holing-amulet-cid'], meta: { values: { 'splice.lfdecentralizedtrust.org/reason': 'demo transfer by LoopSDK', }, }, }, extraArgs: { context: { values: { 'get-these-from-factory': '', }, }, meta: { values: {}, }, }, }, }, } ], packageIdSelectionPreference: [], disclosedContracts: [], }); // In App component: useEffect(() => { if (account?.partyId) { setDamlCommand(JSON.stringify(getDamlCommandTemplate(account.partyId), null, 2)); } }, [account]); const handleRunTransaction = async () => { // ... implementation to submit damlCommand using provider }; ``` -------------------------------- ### Fetch User Holdings and Active Contracts Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Provides functions to retrieve a user's financial holdings and active smart contracts from the Loop network. It utilizes the connected provider object to make these requests. Error handling is included for failed requests. Dependencies include the Loop SDK provider. ```javascript const handleGetHolding = async () => { if (!provider) return; setIsLoading(true); try { const fetchedHoldings = await provider.getHolding(); console.log('Holdings:', fetchedHoldings); setHoldings(fetchedHoldings); } catch (error) { console.error('Failed to get holdings:', error); alert('Failed to get holdings. See console.'); } finally { setIsLoading(false); } }; const handleFindContract = async () => { if (!provider || !templateId) { alert('Please connect and enter a template ID.'); return; } setIsFindingContract(true); setActiveContract([]); try { const contracts = await provider.getActiveContracts({ templateId }); console.log('Found contracts:', contracts); if (contracts && contracts.length > 0) { setActiveContract(contracts); } else { alert('No active contract found with that template ID.'); } } catch (error) { console.error('Failed to find active contract:', error); alert('Failed to find active contract. See console.'); } finally { setIsFindingContract(false); } }; const handleFindContractByInterface = async () => { if (!provider || !interfaceId) { alert('Please connect and enter an Interface ID.'); return; } setIsFindingByInterface(true); setContractByInterface([]); try { console.log('Finding contract by interface:', interfaceId); const contracts = await provider.getActiveContracts({ interfaceId }); console.log('Found contract by interface:', contracts); if (contracts && contracts.length > 0) { setContractByInterface(contracts); } else { alert('No active contract found with that interface ID.'); } } catch (error) { console.error('Failed to find active contract by interface:', error); alert('Failed to find active contract by interface. See console.'); } finally { setIsFindingByInterface(false); } }; ``` -------------------------------- ### Submit DAML Transaction with Loop SDK Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Handles the submission of a DAML transaction using the Loop SDK provider. It includes error handling and state management for the submission process. Requires a connected provider and a valid JSON-parsed DAML command. ```javascript const handleRunTransaction = async () => { if (!provider) { alert('Please connect first.'); return; } setIsSubmittingTx(true); setTxResult(null); try { const command = JSON.parse(damlCommand); const result = await provider.submitTransaction(command); setTxResult(result); } catch (error) { console.error('Failed to submit transaction:', error); alert('Failed to submit transaction. See console.'); setTxResult({ error: error.message }); } finally { setIsSubmittingTx(false); } }; ``` -------------------------------- ### Sign Arbitrary Message (JavaScript) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/README.md Requests the connected user to sign an arbitrary message using their Loop wallet. This is useful for authentication or other cryptographic operations. Includes basic error handling for the signing process. ```javascript const message = 'Hello, Loop!'; try { const signature = await provider.signMessage(message); console.log('Signature:', signature); } catch (error) { console.error('Signing failed:', error); } ``` -------------------------------- ### Submit DAML Transaction for Asset Transfer using JavaScript Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Submits a DAML transaction to the Canton blockchain for user signing and execution via the Loop wallet. This function requires a provider object, the recipient's party ID, and the amount to transfer. It retrieves a transfer factory contract, constructs a DAML command to exercise the 'TransferFactory_Transfer' choice, and submits it for execution. Error handling is included for common issues like user rejection or timeouts. ```javascript async function transferAmulet(provider, recipientPartyId, amount) { try { // First, get the transfer factory contract const factories = await provider.getActiveContracts({ templateId: '#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory' }); if (factories.length === 0) { throw new Error('No transfer factory found'); } const factoryContractId = factories[0]?.contractEntry?.JsActiveContract?.createdEvent?.contractId; // Construct DAML command const damlCommand = { commands: [{ ExerciseCommand: { templateId: '#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory', contractId: factoryContractId, choice: 'TransferFactory_Transfer', choiceArgument: { expectedAdmin: 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a', transfer: { sender: provider.party_id, receiver: recipientPartyId, amount: amount.toString(), instrumentId: { admin: 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a', id: 'Amulet', }, requestedAt: new Date().toISOString(), executeBefore: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), lock: null, inputHoldingCids: [], meta: { values: { 'splice.lfdecentralizedtrust.org/reason': 'Transfer via Loop SDK' } }, }, extraArgs: { context: { values: {} }, meta: { values: {} } }, } } }], packageIdSelectionPreference: [], disclosedContracts: [], }; // Submit transaction - user will be prompted to sign in Loop wallet const result = await provider.submitTransaction(damlCommand); console.log('Transaction successful:', result); return result; } catch (error) { if (error.message === 'Request was rejected by the wallet.') { console.log('User rejected the transaction'); } else if (error.message.includes('timed out')) { console.log('Transaction request timed out'); } else { console.error('Transaction failed:', error); } throw error; } } // Usage transferAmulet( window.loopProvider, '510ae534b026134d27e23ee14ac83be3::1220e21e937baf58245ad64e5e4a903a6b6c46e86c6d12dc0d7408be746fb804b56d', 1.5 ); ``` -------------------------------- ### Query Active Contracts by Template ID in JavaScript Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Fetches active DAML contracts matching a specific template ID. It logs the count and details of found contracts. Dependencies include the provider object from the Loop SDK. Input is a provider object, and output is an array of contracts or an error. ```javascript async function findAmuletContracts(provider) { try { const contracts = await provider.getActiveContracts({ templateId: '#splice-amulet:Splice.Amulet:Amulet' }); console.log(`Found ${contracts.length} Amulet contracts`); contracts.forEach((contract, index) => { const createdEvent = contract?.contractEntry?.JsActiveContract?.createdEvent; if (createdEvent) { console.log(`Contract ${index + 1}:`); console.log(` Contract ID: ${createdEvent.contractId}`); console.log(` Template ID: ${createdEvent.templateId}`); console.log(` Arguments:`, createdEvent.createArguments); } }); return contracts; } catch (error) { console.error('Failed to query contracts:', error); throw error; } } // Usage const amuletContracts = await findAmuletContracts(window.loopProvider); ``` -------------------------------- ### Sign Arbitrary Message using Loop Wallet Private Key (JavaScript) Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Requests the user to sign an arbitrary text message using their Loop wallet's private key. This function takes a provider object and the message to be signed. It returns the original message, the generated signature, the party ID of the signer, and their public key. This signature can subsequently be used for authentication or verification purposes. Includes error handling for rejections and timeouts. ```javascript async function signMessage(provider, message) { try { const signature = await provider.signMessage(message); console.log('Message:', message); console.log('Signature:', signature); console.log('Signed by:', provider.party_id); console.log('Public key:', provider.public_key); // Signature can be used for authentication or verification return { message, signature, partyId: provider.party_id, publicKey: provider.public_key, timestamp: new Date().toISOString(), }; } catch (error) { if (error.message === 'Request was rejected by the wallet.') { console.log('User rejected signing request'); } else if (error.message.includes('timed out')) { console.log('Signing request timed out after 30 seconds'); } else { console.error('Failed to sign message:', error); } throw error; } } // Usage examples signMessage(window.loopProvider, 'Hello, Loop!'); signMessage(window.loopProvider, JSON.stringify({ action: 'authenticate', timestamp: Date.now(), nonce: Math.random().toString(36), })); ``` -------------------------------- ### Query Active Contracts by Interface ID in JavaScript Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Fetches active DAML contracts that implement a given interface ID. It logs the total count and extracts contract IDs. Dependencies include the provider object from the Loop SDK. Input is a provider object, and output is an object containing contracts and their IDs or an error. ```javascript async function findHoldingContracts(provider) { try { const contracts = await provider.getActiveContracts({ interfaceId: '#splice-api-token-holding-v1:Splice.Api.Token.HoldingV1:Holding' }); console.log(`Found ${contracts.length} Holding contracts`); // Extract contract IDs const contractIds = contracts .map(c => c?.contractEntry?.JsActiveContract?.createdEvent?.contractId) .filter(Boolean); console.log('Contract IDs:', contractIds); return { contracts, contractIds }; } catch (error) { console.error('Failed to query contracts by interface:', error); throw error; } } // Usage const { contracts, contractIds } = await findHoldingContracts(window.loopProvider); ``` -------------------------------- ### Find Active Contracts by Template ID (Loop SDK) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Queries the ledger for active contracts matching a given template ID using the Loop SDK. It takes a template ID as input and returns a list of found contract IDs and their details. Requires a connected provider. ```javascript const handleFindContract = async () => { if (!provider) { alert('Please connect first.'); return; } setIsFindingContract(true); setActiveContract([]); try { const contracts = await provider.queryActiveContracts(templateId); setActiveContract(contracts); } catch (error) { console.error('Failed to find contracts:', error); alert('Failed to find contracts. See console.'); } finally { setIsFindingContract(false); } }; ``` -------------------------------- ### Handle Transaction Errors with Loop SDK (JavaScript) Source: https://context7.com/fivenorth-io/loop-sdk/llms.txt Provides a function to safely submit transactions using the Loop SDK, catching and categorizing potential errors such as user rejection, request timeouts, or connection issues. It returns a structured result indicating success or failure with specific error details. ```javascript import { loop } from '@fivenorth/loop-sdk'; async function handleTransaction(provider, command) { try { const result = await provider.submitTransaction(command); return { success: true, data: result }; } catch (error) { // Check error type if (error.constructor.name === 'RejectRequestError') { return { success: false, error: 'rejected', message: 'User rejected the transaction in Loop wallet', }; } else if (error.constructor.name === 'RequestTimeoutError') { return { success: false, error: 'timeout', message: 'Transaction request timed out after 30 seconds', }; } else if (error.message.includes('Not connected')) { return { success: false, error: 'not_connected', message: 'WebSocket connection not established', }; } else { return { success: false, error: 'unknown', message: error.message, }; } } } // Usage const result = await handleTransaction(window.loopProvider, damlCommand); if (!result.success) { console.error(`Transaction failed: ${result.error}`, result.message); } ``` -------------------------------- ### Find Active Contracts by Interface ID (Loop SDK) Source: https://github.com/fivenorth-io/loop-sdk/blob/main/demo/test.html Searches the ledger for active contracts associated with a specific interface ID using the Loop SDK. This function takes an interface ID and returns matching contracts. Requires a connected provider. ```javascript const handleFindContractByInterface = async () => { if (!provider) { alert('Please connect first.'); return; } setIsFindingByInterface(true); setContractByInterface([]); try { const contracts = await provider.queryActiveContractsByInterface(interfaceId); setContractByInterface(contracts); } catch (error) { console.error('Failed to find contracts by interface:', error); alert('Failed to find contracts by interface. See console.'); } finally { setIsFindingByInterface(false); } }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.