From 5f6a3658862860399d535781a4767cf6eb3e54fb Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Fri, 17 Apr 2026 14:16:05 +0200 Subject: [PATCH 1/4] Update lsp-factory.js docs for v4 (remove deprecated status) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove '(deprecated)' label and uncollapse category sidebar - Add Node.js 22+ and TypeScript 5.9+ requirements note - Split install: erc725.js is now optional (only for LSP3 encoding) - Add Version History section noting v4 rewrite (ethers.js → viem, LSP23 atomic deployment) Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/tools/dapps/lsp-factoryjs/_category_.yml | 4 ++-- .../dapps/lsp-factoryjs/getting-started.md | 23 ++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/tools/dapps/lsp-factoryjs/_category_.yml b/docs/tools/dapps/lsp-factoryjs/_category_.yml index 4ff0625bbb..78daab8097 100644 --- a/docs/tools/dapps/lsp-factoryjs/_category_.yml +++ b/docs/tools/dapps/lsp-factoryjs/_category_.yml @@ -1,3 +1,3 @@ -label: '🏭 lsp-factory.js (deprecated)' -collapsed: true +label: '🏭 lsp-factory.js' +collapsed: false position: 7 diff --git a/docs/tools/dapps/lsp-factoryjs/getting-started.md b/docs/tools/dapps/lsp-factoryjs/getting-started.md index 0af2660d92..13e5d0fbe1 100644 --- a/docs/tools/dapps/lsp-factoryjs/getting-started.md +++ b/docs/tools/dapps/lsp-factoryjs/getting-started.md @@ -8,6 +8,13 @@ sidebar_position: 1.1 v4 uses [viem](https://viem.sh/) for all blockchain interactions and deploys contracts atomically via [LSP23LinkedContractsFactory](/standards/factories/lsp23-linked-contracts-factory). +:::info Requirements + +- Node.js >= 22 +- TypeScript >= 5.9 + +::: + ## Supported Networks All contracts (LSP23 factory, base implementations) are deployed at the same deterministic addresses across chains via the [Nick Factory (EIP-2470)](https://eips.ethereum.org/EIPS/eip-2470). @@ -24,9 +31,18 @@ All contracts (LSP23 factory, base implementations) are deployed at the same det ## Installation ```bash -npm install @lukso/lsp-factory.js @erc725/erc725.js +npm install @lukso/lsp-factory.js ``` +:::tip +If you want to encode LSP3 profile metadata or custom controller permissions, also install [erc725.js](https://docs.lukso.tech/tools/dapps/erc725js/getting-started): + +```bash +npm install @erc725/erc725.js +``` + +::: + ## Setup Create a [viem](https://viem.sh/) `PublicClient` (for reading) and `WalletClient` (for signing transactions), then pass them to `LSPFactory`: @@ -225,6 +241,11 @@ const contracts = await factory.UniversalProfile.deploy( ); ``` +## Version History + +- **v4 (3.3.x)** — Complete rewrite: ethers.js replaced with [viem](https://viem.sh/), IPFS upload removed, atomic deployment via [LSP23](/standards/factories/lsp23-linked-contracts-factory). Node.js 22+ required. +- **v3 and earlier** — Used ethers.js, included IPFS upload, deployed contracts individually. + ## Next steps - [Edit Universal Profile metadata](/learn/universal-profile/metadata/edit-profile) From 8ebca35408d1d632b66849a5ab004d47a6dfd4d7 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Fri, 17 Apr 2026 14:22:58 +0200 Subject: [PATCH 2/4] docs: rewrite lsp-factory.js getting-started for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Lead with what the library does and why, not just what it deploys - Move Quick Start (install → deploy in one flow) to the top - Restructure sections by user intent: UP options, tokens, events - Replace jargon with plain explanations (e.g., 'smart accounts' not just 'LSP0') - Move Supported Networks to the bottom (reference, not intro) - Add token ID format table for LSP8 - Remove Version History section (not user-facing) - Keep all code examples accurate to v4 API --- .gitignore | 2 +- .../dapps/lsp-factoryjs/getting-started.md | 160 ++++++++---------- 2 files changed, 74 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index f882c3d82f..cd2449c13e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ yarn-error.log* !.yarn/plugins !.yarn/releases !.yarn/sdks -!.yarn/versions \ No newline at end of file +!.yarn/versionspackage-lock.json diff --git a/docs/tools/dapps/lsp-factoryjs/getting-started.md b/docs/tools/dapps/lsp-factoryjs/getting-started.md index 13e5d0fbe1..79db3b5334 100644 --- a/docs/tools/dapps/lsp-factoryjs/getting-started.md +++ b/docs/tools/dapps/lsp-factoryjs/getting-started.md @@ -4,9 +4,13 @@ sidebar_position: 1.1 # Getting Started -`@lukso/lsp-factory.js` is a helper library for deploying [Universal Profiles](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-0-ERC725Account.md), [LSP7 Digital Assets](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-7-DigitalAsset.md), and [LSP8 Identifiable Digital Assets](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-8-IdentifiableDigitalAsset.md). +`@lukso/lsp-factory.js` makes it easy to deploy smart accounts and tokens on LUKSO (and other EVM chains). Instead of manually deploying and wiring up multiple contracts, the factory handles everything in a single call: -v4 uses [viem](https://viem.sh/) for all blockchain interactions and deploys contracts atomically via [LSP23LinkedContractsFactory](/standards/factories/lsp23-linked-contracts-factory). +- **[Universal Profiles](/standards/accounts/lsp0-erc725account)** — smart accounts with a built-in [Key Manager](/standards/access-control/lsp6-key-manager) for access control and a [Universal Receiver](/standards/accounts/lsp1-universal-receiver) for reacting to transactions +- **[LSP7 Digital Assets](/standards/tokens/LSP7-Digital-Asset)** — fungible tokens (like ERC-20, but with more features) +- **[LSP8 Identifiable Digital Assets](/standards/tokens/LSP8-Identifiable-Digital-Asset)** — NFTs (like ERC-721, but with richer metadata) + +Under the hood, the library uses [LSP23](/standards/factories/lsp23-linked-contracts-factory) to deploy contracts atomically — meaning your Universal Profile and its Key Manager are created together in one transaction, so you never end up with a half-configured account. :::info Requirements @@ -15,37 +19,13 @@ v4 uses [viem](https://viem.sh/) for all blockchain interactions and deploys con ::: -## Supported Networks - -All contracts (LSP23 factory, base implementations) are deployed at the same deterministic addresses across chains via the [Nick Factory (EIP-2470)](https://eips.ethereum.org/EIPS/eip-2470). - -**LSP23 Factory Address:** `0x2300000A84D25dF63081feAa37ba6b62C4c89a30` - -| Network | Chain ID | -| ---------------- | -------- | -| LUKSO Mainnet | 42 | -| LUKSO Testnet | 4201 | -| Ethereum Mainnet | 1 | -| BASE | 8453 | - ## Installation ```bash npm install @lukso/lsp-factory.js ``` -:::tip -If you want to encode LSP3 profile metadata or custom controller permissions, also install [erc725.js](https://docs.lukso.tech/tools/dapps/erc725js/getting-started): - -```bash -npm install @erc725/erc725.js -``` - -::: - -## Setup - -Create a [viem](https://viem.sh/) `PublicClient` (for reading) and `WalletClient` (for signing transactions), then pass them to `LSPFactory`: +## Quick Start ```typescript import { createPublicClient, createWalletClient, http } from 'viem'; @@ -53,6 +33,7 @@ import { privateKeyToAccount } from 'viem/accounts'; import { luksoTestnet } from 'viem/chains'; import { LSPFactory } from '@lukso/lsp-factory.js'; +// 1. Set up your account and clients const account = privateKeyToAccount('0x...'); const publicClient = createPublicClient({ @@ -66,38 +47,42 @@ const walletClient = createWalletClient({ transport: http(), }); +// 2. Create the factory const factory = new LSPFactory(publicClient, walletClient); + +// 3. Deploy a Universal Profile +const contracts = await factory.UniversalProfile.deploy({ + controllerAddresses: [account.address], +}); + +console.log('UP Address:', contracts.LSP0ERC725Account.address); +console.log('KeyManager:', contracts.LSP6KeyManager.address); ``` -:::tip -You can use any viem-supported chain. Just swap `luksoTestnet` for the chain you want to deploy to: +That's it — you now have a fully configured Universal Profile with a Key Manager, controller permissions, and a Universal Receiver Delegate, all deployed in one transaction. + +:::tip Switching networks +Swap the chain import to deploy on any supported network: ```typescript -import { lukso } from 'viem/chains'; // LUKSO Mainnet (42) -import { luksoTestnet } from 'viem/chains'; // LUKSO Testnet (4201) -import { mainnet } from 'viem/chains'; // Ethereum (1) -import { base } from 'viem/chains'; // BASE (8453) +import { lukso } from 'viem/chains'; // LUKSO Mainnet +import { luksoTestnet } from 'viem/chains'; // LUKSO Testnet +import { mainnet } from 'viem/chains'; // Ethereum +import { base } from 'viem/chains'; // BASE ``` ::: -## Deploying a Universal Profile +## Universal Profile Options -Deploys an [LSP0 Universal Profile](/standards/accounts/lsp0-erc725account) and [LSP6 KeyManager](/standards/access-control/lsp6-key-manager) atomically via [LSP23 Factory](/standards/factories/lsp23-linked-contracts-factory), then configures controller permissions and a Universal Receiver Delegate. +### Adding profile metadata -```typescript -const contracts = await factory.UniversalProfile.deploy({ - controllerAddresses: ['0x...'], // Addresses that will control the UP -}); +To set a name, description, and avatar on your profile, encode the data with [erc725.js](https://docs.lukso.tech/tools/dapps/erc725js/getting-started) first: -console.log('UP Address:', contracts.LSP0ERC725Account.address); -console.log('KeyManager Address:', contracts.LSP6KeyManager.address); +```bash +npm install @erc725/erc725.js ``` -### With LSP3 metadata and a deterministic salt - -First, encode your LSP3Profile metadata using [erc725.js](https://docs.lukso.tech/tools/dapps/erc725js/getting-started): - ```typescript import { ERC725 } from '@erc725/erc725.js'; import LSP3ProfileSchema from '@erc725/erc725.js/schemas/LSP3ProfileMetadata.json'; @@ -111,38 +96,29 @@ const encoded = erc725.encodeData([ }, ]); -const lsp3DataValue = encoded.values[0]; -``` - -Then pass it into the deploy call: - -```typescript const contracts = await factory.UniversalProfile.deploy( { controllerAddresses: ['0x...'], - lsp3DataValue, // Pre-encoded LSP3Profile VerifiableURI + lsp3DataValue: encoded.values[0], }, { - salt: '0x...', // bytes32 salt for deterministic address generation + salt: '0x...', // optional: makes the deployed address deterministic }, ); ``` -### With custom controller permissions +### Setting controller permissions + +By default, every address in `controllerAddresses` gets full permissions. You can restrict specific controllers: ```typescript import { ERC725 } from '@erc725/erc725.js'; -// Replace with the correct addresses for your controllers -const adminController = '0x...'; -const restrictedController = '0x...'; - const contracts = await factory.UniversalProfile.deploy({ controllerAddresses: [ - // Gets ALL_PERMISSIONS by default - adminController, + '0xAdmin...', // full permissions (ALL_PERMISSIONS) { - address: restrictedController, + address: '0xRestricted...', permissions: ERC725.encodePermissions({ SUPER_SETDATA: true }), }, ], @@ -151,33 +127,33 @@ const contracts = await factory.UniversalProfile.deploy({ ### Pre-computing addresses -Compute the UP and KeyManager addresses before deploying: +If you need to know the contract addresses before deploying (e.g., for cross-contract references), use the same salt: ```typescript const { upAddress, keyManagerAddress } = await factory.UniversalProfile.computeAddress( { controllerAddresses: ['0x...'] }, - { salt: '0x...' }, // Use the same salt you will deploy with + { salt: '0x...' }, ); ``` -## Deploying an LSP7 Digital Asset +## Deploying Tokens -Deploys an [LSP7 Digital Asset](/standards/tokens/LSP7-Digital-Asset) (fungible token) as a minimal proxy: +### LSP7 — Fungible Tokens ```typescript const contracts = await factory.LSP7DigitalAsset.deploy({ name: 'My Token', symbol: 'MTK', - controllerAddress: '0x...', // Owner of the token contract + controllerAddress: '0x...', // token contract owner tokenType: 0, // 0 = Token, 1 = NFT, 2 = Collection - isNFT: false, // Whether the token is non-divisible + isNFT: false, // true = non-divisible (0 decimals) }); -console.log('LSP7 Address:', contracts.LSP7DigitalAsset.address); +console.log('Token address:', contracts.LSP7DigitalAsset.address); ``` -### With metadata +#### With metadata ```typescript const contracts = await factory.LSP7DigitalAsset.deploy({ @@ -189,16 +165,14 @@ const contracts = await factory.LSP7DigitalAsset.deploy({ digitalAssetMetadata: { verification: { method: 'keccak256(bytes)', - data: '0x...', // keccak256 hash of the JSON metadata file bytes + data: '0x...', // hash of the JSON metadata file }, url: 'ipfs://Qm...', }, }); ``` -## Deploying an LSP8 Identifiable Digital Asset - -Deploys an [LSP8 Identifiable Digital Asset](/standards/tokens/LSP8-Identifiable-Digital-Asset) (NFT) as a minimal proxy: +### LSP8 — NFTs ```typescript const contracts = await factory.LSP8IdentifiableDigitalAsset.deploy({ @@ -206,21 +180,25 @@ const contracts = await factory.LSP8IdentifiableDigitalAsset.deploy({ symbol: 'MNFT', controllerAddress: '0x...', tokenType: 1, // 0 = Token, 1 = NFT, 2 = Collection - // Token ID format constants (from @lukso/lsp8-contracts): - // 0 = UNIQUE_ID (unique bytes32) - // 1 = NUMBER (sequential uint256) - // 2 = STRING (human-readable string) - // 3 = ADDRESS (address packed in bytes32) - // 4 = HASH (keccak256 hash) - tokenIdFormat: 1, + tokenIdFormat: 1, // how token IDs are structured (see below) }); -console.log('LSP8 Address:', contracts.LSP8IdentifiableDigitalAsset.address); +console.log('NFT address:', contracts.LSP8IdentifiableDigitalAsset.address); ``` -## Deployment Events +**Token ID formats:** + +| Value | Format | Description | +| ----- | ------------ | ------------------------------ | +| 0 | `UNIQUE_ID` | Unique `bytes32` | +| 1 | `NUMBER` | Sequential number | +| 2 | `STRING` | Human-readable string | +| 3 | `ADDRESS` | Address packed in `bytes32` | +| 4 | `HASH` | `keccak256` hash | -All `deploy` methods accept an `onDeployEvents` callback for tracking deployment progress: +## Tracking Deployment Progress + +All `deploy` methods accept an `onDeployEvents` callback: ```typescript const contracts = await factory.UniversalProfile.deploy( @@ -241,12 +219,20 @@ const contracts = await factory.UniversalProfile.deploy( ); ``` -## Version History +## Supported Networks -- **v4 (3.3.x)** — Complete rewrite: ethers.js replaced with [viem](https://viem.sh/), IPFS upload removed, atomic deployment via [LSP23](/standards/factories/lsp23-linked-contracts-factory). Node.js 22+ required. -- **v3 and earlier** — Used ethers.js, included IPFS upload, deployed contracts individually. +The factory contracts are deployed at the same addresses on all supported chains via deterministic deployment ([EIP-2470](https://eips.ethereum.org/EIPS/eip-2470)): + +| Network | Chain ID | +| ---------------- | -------- | +| LUKSO Mainnet | 42 | +| LUKSO Testnet | 4201 | +| Ethereum Mainnet | 1 | +| BASE | 8453 | + +**LSP23 Factory Address:** `0x2300000A84D25dF63081feAa37ba6b62C4c89a30` -## Next steps +## Next Steps - [Edit Universal Profile metadata](/learn/universal-profile/metadata/edit-profile) - [Deploying tokens and NFTs](/learn/digital-assets/getting-started) From 7c7686d50cd1544e2e693413e51ee973fa4ab5d4 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Fri, 17 Apr 2026 15:20:44 +0200 Subject: [PATCH 3/4] fix: prettier formatting --- docs/tools/dapps/lsp-factoryjs/getting-started.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/tools/dapps/lsp-factoryjs/getting-started.md b/docs/tools/dapps/lsp-factoryjs/getting-started.md index 79db3b5334..d3939811ad 100644 --- a/docs/tools/dapps/lsp-factoryjs/getting-started.md +++ b/docs/tools/dapps/lsp-factoryjs/getting-started.md @@ -188,13 +188,13 @@ console.log('NFT address:', contracts.LSP8IdentifiableDigitalAsset.address); **Token ID formats:** -| Value | Format | Description | -| ----- | ------------ | ------------------------------ | -| 0 | `UNIQUE_ID` | Unique `bytes32` | -| 1 | `NUMBER` | Sequential number | -| 2 | `STRING` | Human-readable string | -| 3 | `ADDRESS` | Address packed in `bytes32` | -| 4 | `HASH` | `keccak256` hash | +| Value | Format | Description | +| ----- | ----------- | --------------------------- | +| 0 | `UNIQUE_ID` | Unique `bytes32` | +| 1 | `NUMBER` | Sequential number | +| 2 | `STRING` | Human-readable string | +| 3 | `ADDRESS` | Address packed in `bytes32` | +| 4 | `HASH` | `keccak256` hash | ## Tracking Deployment Progress From 799205d1e8f900f1a2caacd5597b127306337db1 Mon Sep 17 00:00:00 2001 From: emmet-bot Date: Fri, 17 Apr 2026 15:21:09 +0200 Subject: [PATCH 4/4] chore: ignore package-lock.json --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cd2449c13e..20454aebb8 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ yarn-error.log* !.yarn/releases !.yarn/sdks !.yarn/versionspackage-lock.json +package-lock.json