diff --git a/examples/x-to-zkevm-migration-app/backend/README.md b/examples/x-to-zkevm-migration-app/backend/README.md index 8c56e10936..ffb7ba06b1 100644 --- a/examples/x-to-zkevm-migration-app/backend/README.md +++ b/examples/x-to-zkevm-migration-app/backend/README.md @@ -5,10 +5,11 @@ A sample backend service that listens for NFT transfers to a burn address on Imm ## Overview This service: -1. Listens for transfer events via webhooks from Immutable X -2. When an NFT is transferred to the burn address (0x0000000000000000000000000000000000000000) from a specified collection -3. Creates a mint request for the same NFT on Immutable zkEVM -4. Uses the minting-backend module to handle the minting process +1. Registers migrations in a migrations table to track the migration process. +2. Listens for transfer events via webhooks from Immutable X +3. When an NFT is transferred to the burn address (0x0000000000000000000000000000000000000000) from a specified collection +4. Creates a mint request for the same NFT on Immutable zkEVM +5. Uses the minting-backend module to handle the minting process ## Getting Started @@ -61,6 +62,7 @@ localhost:3001 # Postgres localhost:5432 ``` + ## Expose Local Port for Webhooks You can use services like below to expose ports locally. @@ -110,10 +112,17 @@ The service uses: 3. If transfer matches criteria: - Creates mint request for zkEVM - Submits mint request via minting backend -4. Minting backend handles the actual minting process -5. Service receives mint status updates via webhook +4. Listens for burn events and verifies corresponding migration in the migrations table before minting. +5. Minting backend handles the actual minting process +6. Updates the migration record when a mint event occurs. ## Database The service uses PostgreSQL for persistence. Tables are automatically created on startup: - Uses `im_assets` tables for mint requests +- Includes a `migrations` table to track migration registrations. + +## APIs + +- **POST /migrations**: API to register a new migration. +- **GET /migrations**: API to retrieve all pending migrations. diff --git a/examples/x-to-zkevm-migration-app/backend/docker-compose.yml b/examples/x-to-zkevm-migration-app/backend/docker-compose.yml index 80bcc4492c..31ec5f2329 100644 --- a/examples/x-to-zkevm-migration-app/backend/docker-compose.yml +++ b/examples/x-to-zkevm-migration-app/backend/docker-compose.yml @@ -13,6 +13,7 @@ services: - 5432:5432 volumes: - ../../../packages/minting-backend/sdk/src/persistence/pg/seed.sql:/docker-entrypoint-initdb.d/seed.sql + - ./persistence/migrations/seed.sql:/docker-entrypoint-initdb.d/migrations_seed.sql backend: image: node:20-alpine restart: always diff --git a/examples/x-to-zkevm-migration-app/backend/index.ts b/examples/x-to-zkevm-migration-app/backend/index.ts index a06bee4628..48caa45d3d 100644 --- a/examples/x-to-zkevm-migration-app/backend/index.ts +++ b/examples/x-to-zkevm-migration-app/backend/index.ts @@ -1,14 +1,20 @@ +import cors from '@fastify/cors'; import { config, mintingBackend, webhook } from '@imtbl/sdk'; import 'dotenv/config'; -import Fastify from 'fastify'; +import Fastify, { FastifyRequest } from 'fastify'; import { Pool } from 'pg'; import { v4 as uuidv4 } from 'uuid'; - +import { migrationPersistence } from './persistence/postgres'; const fastify = Fastify({ logger: true }); +// Enable CORS +fastify.register(cors, { + origin: '*', +}); + // setup database client const pgClient = new Pool({ user: process.env.PG_USER || 'postgres', @@ -18,6 +24,8 @@ const pgClient = new Pool({ port: 5432, }); +const migrations = migrationPersistence(pgClient); + // persistence setup for minting backend const mintingPersistence = mintingBackend.mintingPersistencePg(pgClient); @@ -39,9 +47,24 @@ fastify.post('/webhook', async (request, reply) => { { zkevmMintRequestUpdated: async (event) => { console.log('Received webhook event:', event); + const tokenAddress = event.data.contract_address; + const tokenId = event.data.token_id || ''; + + // Update migration status + if (tokenAddress && tokenId && event.data.status === 'succeeded') { + const migration = await migrations.getMigration(tokenId, { zkevmCollectionAddress: tokenAddress }); + if (!migration) { + console.log(`Migration record not found for minted token ${tokenId}`); + return; + } + + await migrations.updateMigration(migration.id, { + status: 'minted', + }); + } await minting.processMint(request.body as any); - console.log('Processed minting update:', event); + console.log('Processed minting update'); }, xTransferCreated: async (event) => { console.log('Received webhook event:', event); @@ -50,17 +73,39 @@ fastify.post('/webhook', async (request, reply) => { event.data.receiver.toLowerCase() === process.env.IMX_BURN_ADDRESS?.toLowerCase() && event.data.token?.data?.token_address?.toLowerCase() === process.env.IMX_MONITORED_COLLECTION_ADDRESS?.toLowerCase() ) { - // Create mint request on zkEVM - let mintRequest = { - asset_id: uuidv4(), - contract_address: process.env.ZKEVM_COLLECTION_ADDRESS!, - owner_address: event.data.user, - token_id: event.data.token.data.token_id, - metadata: {} // Add any metadata if needed - }; - await minting.recordMint(mintRequest); - - console.log(`Created mint request for burned token ${event.data.token.data.token_id}`); + // Check if we have a migration record for this token + const tokenAddress = event.data.token?.data?.token_address; + const tokenId = event.data.token?.data?.token_id; + + if (tokenAddress && tokenId) { + const migration = await migrations.getMigration(tokenId, { xCollectionAddress: tokenAddress }); + if (!migration) { + console.log(`Migration record not found for burned token ${tokenId}`); + return; + } + + // Update migration status + await migrations.updateMigration(migration.id, { + burn_id: event.data.transaction_id.toString(), + status: 'burned', + }); + + // Create mint request on zkEVM + let mintRequest = { + asset_id: uuidv4(), + contract_address: process.env.ZKEVM_COLLECTION_ADDRESS!, + owner_address: migration.zkevm_wallet_address, + token_id: migration.token_id, + metadata: {} // Add any metadata if needed + }; + await minting.recordMint(mintRequest); + + console.log(`Updated migration status for burned token ${tokenId}`); + + console.log(`Created mint request for burned token ${event.data.token.data.token_id}`); + } else { + console.log('Token address or token ID is undefined'); + } } } } @@ -75,6 +120,43 @@ fastify.post('/webhook', async (request, reply) => { }); } }); +interface MigrationRequest { + migrationReqs: { + zkevm_wallet_address: string; + token_id: string; + }[]; +} + +// New endpoint to create or upsert a list of migrations +fastify.post('/migrations', async (request: FastifyRequest<{ Body: MigrationRequest }>, reply) => { + const { migrationReqs } = request.body; + + try { + for (const migration of migrationReqs) { + await migrations.insertMigration({ + x_collection_address: process.env.IMX_MONITORED_COLLECTION_ADDRESS!, + zkevm_collection_address: process.env.ZKEVM_COLLECTION_ADDRESS!, + zkevm_wallet_address: migration.zkevm_wallet_address, + token_id: migration.token_id, + status: 'pending' + }); + } + return reply.status(201).send({ message: 'Migrations created successfully' }); + } catch (error) { + console.error(error); + return reply.status(500).send({ message: 'Error creating migrations' }); + } +}); + +fastify.get('/migrations', async (request, reply) => { + try { + const pendingMigrations = await migrations.getAllPendingMigrations(); // Adjust this method based on your persistence layer + return reply.status(200).send(pendingMigrations); + } catch (error) { + console.error(error); + return reply.status(500).send({ message: 'Error retrieving migrations' }); + } +}); const start = async () => { try { diff --git a/examples/x-to-zkevm-migration-app/backend/persistence/migrations/seed.sql b/examples/x-to-zkevm-migration-app/backend/persistence/migrations/seed.sql new file mode 100644 index 0000000000..5d40b14ba6 --- /dev/null +++ b/examples/x-to-zkevm-migration-app/backend/persistence/migrations/seed.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS migrations ( + id SERIAL PRIMARY KEY, + x_collection_address VARCHAR NOT NULL, + zkevm_collection_address VARCHAR NOT NULL, + token_id VARCHAR NOT NULL UNIQUE, + zkevm_wallet_address VARCHAR NOT NULL, + status VARCHAR NOT NULL, + burn_id VARCHAR, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); \ No newline at end of file diff --git a/examples/x-to-zkevm-migration-app/backend/persistence/postgres.ts b/examples/x-to-zkevm-migration-app/backend/persistence/postgres.ts new file mode 100644 index 0000000000..fd9bdb2fa0 --- /dev/null +++ b/examples/x-to-zkevm-migration-app/backend/persistence/postgres.ts @@ -0,0 +1,72 @@ +import type { Pool } from 'pg'; + +export const migrationPersistence = (client: Pool) => { + return { + insertMigration: async (migrationData: { + x_collection_address: string; + zkevm_collection_address: string; + zkevm_wallet_address: string; + token_id: string; + status: string; + }) => { + const result = await client.query( + ` + INSERT INTO migrations (x_collection_address, zkevm_collection_address, zkevm_wallet_address, token_id, status) + VALUES ($1, $2, $3, $4, $5); + `, + [ + migrationData.x_collection_address, + migrationData.zkevm_collection_address, + migrationData.zkevm_wallet_address, + migrationData.token_id, + migrationData.status, + ] + ); + return result.rowCount !== null && result.rowCount > 0; + }, + + getMigration: async (tokenId: string, options?: { xCollectionAddress?: string; zkevmCollectionAddress?: string }) => { + let query = ` + SELECT * FROM migrations WHERE token_id = $1 + `; + let values = [tokenId]; + + if (options?.xCollectionAddress) { + query += ` AND x_collection_address = $2;`; + values.push(options.xCollectionAddress); + } else if (options?.zkevmCollectionAddress) { + query += ` AND zkevm_collection_address = $2;`; + values.push(options.zkevmCollectionAddress); + } + + const res = await client.query(query, values); + return res.rows[0] || null; + }, + + getAllPendingMigrations: async () => { + const res = await client.query( + ` + SELECT * FROM migrations WHERE status = 'pending'; + ` + ); + return res.rows || []; + }, + + updateMigration: async (id: string, updateData: Partial<{ + status?: string; + burn_id?: string; + }>) => { + const fields = Object.keys(updateData).map((key, index) => `${key} = $${index + 2}`).join(', '); + const values = [id, ...Object.values(updateData)]; + const result = await client.query( + ` + UPDATE migrations + SET ${fields} + WHERE id = $1; + `, + values + ); + return result.rowCount !== null && result.rowCount > 0; + }, + }; +}; \ No newline at end of file diff --git a/examples/x-to-zkevm-migration-app/frontend/.env.example b/examples/x-to-zkevm-migration-app/frontend/.env.example index ff6b2e1b0e..e06d9f8b56 100644 --- a/examples/x-to-zkevm-migration-app/frontend/.env.example +++ b/examples/x-to-zkevm-migration-app/frontend/.env.example @@ -3,3 +3,5 @@ NEXT_PUBLIC_BURN_ADDRESS=0x0000000000000000000000000000000000000000 # or whateve NEXT_PUBLIC_PUBLISHABLE_KEY= NEXT_PUBLIC_CLIENT_ID= NEXT_PUBLIC_ALCHEMY_API_KEY= +NEXT_PUBLIC_IMX_COLLECTION_ADDRESS= +NEXT_PUBLIC_ZKEVM_COLLECTION_ADDRESS= diff --git a/examples/x-to-zkevm-migration-app/frontend/README.md b/examples/x-to-zkevm-migration-app/frontend/README.md index cba6f02208..accad2d0bf 100644 --- a/examples/x-to-zkevm-migration-app/frontend/README.md +++ b/examples/x-to-zkevm-migration-app/frontend/README.md @@ -4,10 +4,10 @@ This React application allows users to migrate their NFTs from Immutable X to Im ## Features -- **Login with Passport**: Securely connect your wallet using Immutable Passport. -- **View Immutable X Assets**: Display NFTs available for migration from Immutable X. -- **View zkEVM Assets**: Display NFTs on zkEVM, including those migrated from Immutable X. -- **Migrate NFTs**: Initiate a burn on Immutable X and mint the equivalent NFT on zkEVM. +- **Login with Passport or Link for IMX**: Securely connect your wallet using Immutable Passport or Link for Immutable X. +- **Login with Passport for zkEVM**: Connect your wallet using Immutable Passport for zkEVM. +- **Stage Assets for Migration**: Stage your assets before initiating the migration process. +- **Migrate All NFTs**: Click "Migrate All" to burn all staged assets on Immutable X and mint them on zkEVM. ## Prerequisites @@ -34,6 +34,8 @@ This React application allows users to migrate their NFTs from Immutable X to Im NEXT_PUBLIC_PUBLISHABLE_KEY= NEXT_PUBLIC_CLIENT_ID= NEXT_PUBLIC_API_KEY= + NEXT_PUBLIC_IMX_COLLECTION_ADDRESS= # Add your IMX collection address + NEXT_PUBLIC_ZKEVM_COLLECTION_ADDRESS= # Add your zkEVM collection address ``` 3. **Start the development server**: @@ -46,18 +48,19 @@ This React application allows users to migrate their NFTs from Immutable X to Im ## Usage 1. **Connect Wallet** - - Click "Connect Wallet" to authenticate using Passport + - Click "Connect Wallet" to authenticate using Link or Passport for IMX - Approve the connection request + - For zkEVM, click "Connect Wallet" to authenticate using Passport only 2. **View Your NFTs** - **IMX NFTs**: Shows your available NFTs for migration - **zkEVM NFTs**: Shows your NFTs on zkEVM network 3. **Migrate NFTs** - - Select an NFT from your IMX collection - - Click "Migrate" to initiate the transfer to the burn address - - The backend will detect the burn and mint on zkEVM - - New NFT will appear in the zkEVM tab once minted + - Stage your NFTs for migration + - Click "Migrate All" to initiate the transfer to the burn address + - The backend will detect the burns and mint on zkEVM + - New NFTs will appear in the zkEVM tab once minted ## Development diff --git a/examples/x-to-zkevm-migration-app/frontend/package.json b/examples/x-to-zkevm-migration-app/frontend/package.json index 44be560ad1..25816adcbb 100644 --- a/examples/x-to-zkevm-migration-app/frontend/package.json +++ b/examples/x-to-zkevm-migration-app/frontend/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@biom3/react": "^0.27.25", + "@imtbl/imx-sdk": "^3.8.2", "@imtbl/sdk": "^1.52.0", "dotenv": "^16.4.5", "next": "14.2.10", diff --git a/examples/x-to-zkevm-migration-app/frontend/src/app/layout.tsx b/examples/x-to-zkevm-migration-app/frontend/src/app/layout.tsx index c80a704698..6e3b7e9bc6 100644 --- a/examples/x-to-zkevm-migration-app/frontend/src/app/layout.tsx +++ b/examples/x-to-zkevm-migration-app/frontend/src/app/layout.tsx @@ -1,10 +1,13 @@ 'use client'; +import { BackendProvider } from '@/context/backend'; import { IMXProvider } from '@/context/imx'; +import { LinkProvider } from '@/context/link'; import { PassportProvider } from '@/context/passport'; import { ZkEVMProvider } from '@/context/zkevm'; import { BiomeCombinedProviders } from '@biom3/react'; import { Inter } from 'next/font/google'; +import React from 'react'; import './globals.css'; const inter = Inter({ subsets: ['latin'] }) @@ -17,15 +20,19 @@ export default function RootLayout({ return ( - - - - - {children} - - - - + + + + + + + {children} + + + + + + ) diff --git a/examples/x-to-zkevm-migration-app/frontend/src/app/page.tsx b/examples/x-to-zkevm-migration-app/frontend/src/app/page.tsx index 4364894807..fe0990987f 100644 --- a/examples/x-to-zkevm-migration-app/frontend/src/app/page.tsx +++ b/examples/x-to-zkevm-migration-app/frontend/src/app/page.tsx @@ -1,48 +1,106 @@ 'use client'; +import { useBackend } from '@/context/backend'; // Adjust the import path as necessary import { useIMX } from '@/context/imx'; +import { useLink } from '@/context/link'; import { usePassport } from '@/context/passport'; import { useZkEVM } from '@/context/zkevm'; import { Box, Button, Grid, Heading, Stack } from '@biom3/react'; -import { passport } from "@imtbl/sdk"; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; export default function Home() { const { listAssets: listIMXAssets } = useIMX(); const { listAssets: listZKEVMAssets } = useZkEVM(); + const { setupLink, burn: linkBurn } = useLink(); const { - imxWalletAddress, login, logout, - getUserInfo, - burn, + burn: passportBurn, } = usePassport(); - const [userProfile, setUserProfile] = useState(null); + const [imxWalletAddress, setIMXWalletAddress] = useState(null); + const [zkevmWalletAddress, setZKEVMWalletAddress] = useState(null); + const [imxLoginMethod, setImxLoginMethod] = useState<'passport' | 'link' | null>(null); + const [loading, setLoading] = useState(false); const [imxAssets, setIMXAssets] = useState([]); const [zkevmAssets, setZKEVMAssets] = useState([]); const [selectedAssets, setSelectedAssets] = useState([]); - const [loading, setLoading] = useState(false); + const { fetchStagedAssets, stageAssets } = useBackend(); + const [stagedAssets, setStagedAssets] = useState([]); + const [originalIMXAssets, setOriginalIMXAssets] = useState([]); // New state for original assets + + useEffect(() => { + setSelectedAssets([]); + }, []); + + const handleLoginIMXWithLink = async () => { + if (setupLink) { + const address = await setupLink(); + if (address) { + setIMXWalletAddress(address); + setImxLoginMethod('link'); + console.log(`Connected to IMX with Link: ${address}`); + } else { + console.log('Failed to connect to IMX with Link'); + } + } + }; - const handleLogin = async () => { + const handleLoginIMXWithPassport = async () => { if (login) { - await login(); - const profile = await getUserInfo?.(); - if (profile) { - console.log('User info fetched:', profile); - setUserProfile(profile); + const address = await login(); + if (address) { + setIMXWalletAddress(address); + setZKEVMWalletAddress(address); // Log into zkEVM as well + setImxLoginMethod('passport'); + console.log(`Connected to IMX with Passport: ${address}`); } else { - console.log('Failed to fetch user info'); + console.log('Failed to connect to IMX with Passport'); } } }; + const handleLogoutIMX = async () => { + if (imxLoginMethod === 'link') { + setIMXWalletAddress(null); + setImxLoginMethod(null); + console.log('Logged out of IMX with Link'); + } else if (imxLoginMethod === 'passport' && logout) { + await logout(); // Log out from Passport + setIMXWalletAddress(null); + setZKEVMWalletAddress(null); // Also log out of zkEVM + setImxLoginMethod(null); + console.log('Logged out of IMX with Passport'); + } + }; + + const handleLoginZKEVMWithPassport = async () => { + if (login) { + const address = await login(); + if (address) { + setZKEVMWalletAddress(address); + console.log(`Connected to zkEVM with Passport: ${address}`); + } else { + console.log('Failed to connect to zkEVM with Passport'); + } + } + }; + const handleLogoutZKEVM = async () => { + if (logout) { + await logout(); // Log out from Passport + } + setZKEVMWalletAddress(null); + console.log('Logged out of zkEVM'); + }; + const handleListIMXAssets = async () => { if (listIMXAssets) { setLoading(true); try { if (imxWalletAddress) { const assetsResponse = await listIMXAssets(imxWalletAddress); - setIMXAssets(assetsResponse.result); + let filteredAssets = assetsResponse.result.filter((asset: any) => asset.token_address === process.env.NEXT_PUBLIC_IMX_COLLECTION_ADDRESS); + setOriginalIMXAssets(filteredAssets); // Set original assets + setIMXAssets(filteredAssets); // Set displayed assets } else { console.log('IMX wallet address is undefined'); } @@ -58,12 +116,12 @@ export default function Home() { if (listZKEVMAssets) { setLoading(true); try { - if (imxWalletAddress) { - const assetsResponse = await listZKEVMAssets(imxWalletAddress); - setZKEVMAssets(assetsResponse.result); - console.log(`zkevmAssets: `, assetsResponse) + if (zkevmWalletAddress) { + const assetsResponse = await listZKEVMAssets(zkevmWalletAddress); + let filteredAssets = assetsResponse.result.filter((asset: any) => asset.contract_address === process.env.NEXT_PUBLIC_ZKEVM_COLLECTION_ADDRESS); + setZKEVMAssets(filteredAssets); } else { - console.log('IMX wallet address is undefined'); + console.log('ZkEVM wallet address is undefined'); } } catch (error) { console.error('Error listing ZKEVM assets:', error); @@ -73,12 +131,47 @@ export default function Home() { } }; + const handleListStagedAssets = useCallback(async () => { + if (fetchStagedAssets) { + try { + const response = await fetchStagedAssets(); + const stagedAssets = originalIMXAssets.filter((asset: any) => response.some((stagedAsset: any) => stagedAsset.token_id === asset.token_id)); + setStagedAssets(stagedAssets); + } catch (error) { + console.error('Error fetching staged assets:', error); + } + } + }, [fetchStagedAssets, originalIMXAssets]); // Add dependencies + useEffect(() => { - if (userProfile) { - handleListIMXAssets(); + const fetchAssets = async () => { + if (imxWalletAddress) { + await handleListIMXAssets(); + } + }; + fetchAssets(); + }, [imxWalletAddress]); + + useEffect(() => { + if (imxAssets.length > 0) { // Ensure imxAssets is loaded + handleListStagedAssets(); // Call to fetch staged assets only after IMX assets are loaded + } + }, [imxAssets.length]); // Change dependency to imxAssets.length + + useEffect(() => { + if (zkevmWalletAddress) { handleListZKEVMAssets(); } - }, [userProfile]); + }, [zkevmWalletAddress]); + + useEffect(() => { + if (stagedAssets.length > 0) { + // Filter out staged assets from imxAssets + setIMXAssets(originalIMXAssets.filter(asset => + !stagedAssets.some(stagedAsset => stagedAsset.token_id === asset.token_id) + )); + } + }, [stagedAssets, originalIMXAssets]); // Add originalIMXAssets as a dependency const handleAssetSelection = (asset: any) => { setSelectedAssets(prev => @@ -86,12 +179,38 @@ export default function Home() { ); }; - const handleBurn = async () => { - if (userProfile && burn) { + const handleBurnPassport = async () => { + if (passportBurn) { + setLoading(true); + try { + if (imxWalletAddress) { + await passportBurn(stagedAssets.map(asset => ({ + tokenId: asset.token_id, + tokenAddress: asset.token_address, + }))); + + // Clear selection and refresh asset lists + setSelectedAssets([]); + await handleListIMXAssets(); + await handleListZKEVMAssets(); + await handleListStagedAssets(); + } else { + console.error('IMX wallet address is undefined'); + } + } catch (error) { + console.error('Error burning:', error); + } finally { + setLoading(false); + } + } + } + + const handleBurnLink = async () => { + if (linkBurn) { setLoading(true); try { if (imxWalletAddress) { - await burn(selectedAssets.map(asset => ({ + await linkBurn(stagedAssets.map(asset => ({ tokenId: asset.token_id, tokenAddress: asset.token_address, }))); @@ -100,6 +219,7 @@ export default function Home() { setSelectedAssets([]); await handleListIMXAssets(); await handleListZKEVMAssets(); + await handleListStagedAssets(); } else { console.error('IMX wallet address is undefined'); } @@ -109,6 +229,23 @@ export default function Home() { setLoading(false); } } + } + + const handleStageAssets = async () => { + if (selectedAssets.length > 0 && zkevmWalletAddress) { + // Create migration requests and include metadata + const migrationReqs = selectedAssets.map(asset => { + return { + zkevm_wallet_address: zkevmWalletAddress, + token_id: asset.token_id, + }; + }); + + // Stage the assets + await stageAssets(migrationReqs); + await handleListStagedAssets(); + setSelectedAssets([]); // Clear selected assets + } }; return ( @@ -120,18 +257,28 @@ export default function Home() { sx={{ mb: "base.spacing.x4" }} > Immutable X to Immutable zkEVM Asset Migrator - {!userProfile ? ( - + {!imxWalletAddress ? ( + + + + ) : ( - + + + {imxWalletAddress} + + + )} - - {userProfile ? ( + + {imxWalletAddress ? ( <> @@ -139,14 +286,14 @@ export default function Home() { {selectedAssets.length > 0 ? ( ) : null} - + {loading ? ( Loading... ) : ( @@ -207,11 +354,94 @@ export default function Home() { )} - - + + - Immutable zkEVM Assets + Staged Assets + {stagedAssets.length > 0 ? ( + + ) : null} + + + {stagedAssets.map((asset) => ( + + {asset.image_url ? ( + {asset.name} + ) : null} + + {asset.name} + + + ID: {asset.token_id} + + + ))} + + + + + + + Immutable zkEVM Assets + + {!zkevmWalletAddress ? ( + + ) : ( + + + {zkevmWalletAddress} + + + + )} + Promise; + stageAssets: (migrationReqs: { zkevm_wallet_address: string; token_id: string }[]) => Promise; +} + +const BackendContext = createContext(undefined); + +export const BackendProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const apiURL = 'http://localhost:3001/migrations'; + + const fetchStagedAssets = async (): Promise => { + try { + const response = await fetch(apiURL); + if (response.ok) { + const data = await response.json(); + return data as Migration[]; + } else { + console.error('Failed to fetch staged assets'); + return []; + } + } catch (error) { + console.error('Error fetching staged assets:', error); + return []; + } + }; + + const stageAssets = async (migrationReqs: { zkevm_wallet_address: string; token_id: string }[]) => { + try { + const response = await fetch(apiURL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ migrationReqs }), + }); + + if (!response.ok) { + throw new Error('Failed to stage assets'); + } + } catch (error) { + console.error('Error staging assets:', error); + } + }; + + return ( + + {children} + + ); +}; + +export const useBackend = () => { + const context = useContext(BackendContext); + if (!context) { + throw new Error('useBackend must be used within a BackendProvider'); + } + return context; +}; \ No newline at end of file diff --git a/examples/x-to-zkevm-migration-app/frontend/src/context/link.tsx b/examples/x-to-zkevm-migration-app/frontend/src/context/link.tsx new file mode 100644 index 0000000000..51be170909 --- /dev/null +++ b/examples/x-to-zkevm-migration-app/frontend/src/context/link.tsx @@ -0,0 +1,66 @@ +import { ERC721TokenType, Link } from '@imtbl/imx-sdk'; +import React, { createContext, useCallback, useContext, useMemo } from 'react'; + +interface LinkContextType { + setupLink?: () => Promise; + burn?: (nfts: { tokenId: string; tokenAddress: string }[]) => Promise; +} + +const LinkContext = createContext({}); + +export const LinkProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const link = new Link('https://link.sandbox.x.immutable.com'); + const setupLink = useCallback(async () => { + let result; + try { + result = await link.setup({}) + console.log(result) + } + catch (error) { + console.error(error) + } + console.log('MetaMask connected'); + + return result?.address; + }, [link]); + + const burn = useCallback(async (nfts: { tokenId: string; tokenAddress: string }[]) => { + try { + if (link) { + await link.batchNftTransfer( + nfts.map(nft => ({ + type: ERC721TokenType.ERC721, + tokenId: nft.tokenId, + tokenAddress: nft.tokenAddress, + toAddress: process.env.NEXT_PUBLIC_BURN_ADDRESS || '', + })) + ); + } else { + console.log('No link instance available'); + return; + } + console.log('NFTs burned'); + + } catch (error) { + console.error('Error burning NFTs:', error); + } + }, [link]); + + const providerValue = useMemo(() => { + console.log('LinkProvider: Creating provider value'); + return { + setupLink, + burn, + }; + }, [setupLink, burn]); + + return ( + + {children} + + ); +}; + +export const useLink = () => { + return useContext(LinkContext); +}; \ No newline at end of file diff --git a/examples/x-to-zkevm-migration-app/frontend/src/context/passport.tsx b/examples/x-to-zkevm-migration-app/frontend/src/context/passport.tsx index f03846fef6..77f59464c4 100644 --- a/examples/x-to-zkevm-migration-app/frontend/src/context/passport.tsx +++ b/examples/x-to-zkevm-migration-app/frontend/src/context/passport.tsx @@ -8,7 +8,7 @@ type PassportContextType = { passportInstance?: passport.Passport; passportSilentInstance?: passport.Passport; imxWalletAddress?: string; - login?: () => void; + login?: () => Promise; logout?: () => void; getUserInfo?: () => Promise; getLinkedAddresses?: () => Promise; @@ -49,6 +49,8 @@ export function PassportProvider({ children }: { children: React.ReactNode }) { } catch (error) { console.error('login: Error connecting', error); } + + return imxWalletAddress; }, [passportInstance]); const logout = useCallback(async () => { @@ -95,7 +97,7 @@ export function PassportProvider({ children }: { children: React.ReactNode }) { }, [passportInstance]); const burn = useCallback(async (nfts: { tokenId: string; tokenAddress: string }[]): Promise => { - if (!passportInstance || !imxWalletAddress) { + if (!passportInstance) { console.log('burn: No passport instance or wallet address available'); return; } @@ -117,7 +119,7 @@ export function PassportProvider({ children }: { children: React.ReactNode }) { } catch (error) { console.error('burn: Error burning tokens', error); } - }, [passportInstance, imxWalletAddress]); + }, [passportInstance]); const providerValue = useMemo(() => { console.log('PassportProvider: Creating provider value'); diff --git a/yarn.lock b/yarn.lock index cb71ade173..381162bbfc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2319,6 +2319,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.15.4": + version: 7.26.0 + resolution: "@babel/runtime@npm:7.26.0" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: c8e2c0504ab271b3467a261a8f119bf2603eb857a0d71e37791f4e3fae00f681365073cc79f141ddaa90c6077c60ba56448004ad5429d07ac73532be9f7cf28a + languageName: node + linkType: hard + "@babel/runtime@npm:^7.19.4": version: 7.25.0 resolution: "@babel/runtime@npm:7.25.0" @@ -2698,6 +2707,13 @@ __metadata: languageName: node linkType: hard +"@colors/colors@npm:1.6.0, @colors/colors@npm:^1.6.0": + version: 1.6.0 + resolution: "@colors/colors@npm:1.6.0" + checksum: aa209963e0c3218e80a4a20553ba8c0fbb6fa13140540b4e5f97923790be06801fc90172c1114fc8b7e888b3d012b67298cde6b9e81521361becfaee400c662f + languageName: node + linkType: hard + "@confio/ics23@npm:^0.6.8": version: 0.6.8 resolution: "@confio/ics23@npm:0.6.8" @@ -3224,6 +3240,17 @@ __metadata: languageName: node linkType: hard +"@dabh/diagnostics@npm:^2.0.2": + version: 2.0.3 + resolution: "@dabh/diagnostics@npm:2.0.3" + dependencies: + colorspace: 1.1.x + enabled: 2.0.x + kuler: ^2.0.0 + checksum: 4879600c55c8315a0fb85fbb19057bad1adc08f0a080a8cb4e2b63f723c379bfc4283b68123a2b078d367b327dd8df12fcb27464efe791addc0a48b9df6d79a1 + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.11.0": version: 11.11.0 resolution: "@emotion/babel-plugin@npm:11.11.0" @@ -3702,7 +3729,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/abstract-signer@npm:5.7.0, @ethersproject/abstract-signer@npm:^5.7.0": +"@ethersproject/abstract-signer@npm:5.7.0, @ethersproject/abstract-signer@npm:^5.6.0, @ethersproject/abstract-signer@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/abstract-signer@npm:5.7.0" dependencies: @@ -3715,7 +3742,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5.0.0, @ethersproject/address@npm:^5.0.2, @ethersproject/address@npm:^5.7.0": +"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5.0.0, @ethersproject/address@npm:^5.0.2, @ethersproject/address@npm:^5.6.0, @ethersproject/address@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/address@npm:5.7.0" dependencies: @@ -3747,7 +3774,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/bignumber@npm:5.7.0, @ethersproject/bignumber@npm:^5.7.0": +"@ethersproject/bignumber@npm:5.7.0, @ethersproject/bignumber@npm:^5.6.0, @ethersproject/bignumber@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/bignumber@npm:5.7.0" dependencies: @@ -3758,7 +3785,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/bytes@npm:5.7.0, @ethersproject/bytes@npm:^5.7.0": +"@ethersproject/bytes@npm:5.7.0, @ethersproject/bytes@npm:^5.6.0, @ethersproject/bytes@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/bytes@npm:5.7.0" dependencies: @@ -3776,7 +3803,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/contracts@npm:5.7.0, @ethersproject/contracts@npm:^5.7.0": +"@ethersproject/contracts@npm:5.7.0, @ethersproject/contracts@npm:^5.6.0, @ethersproject/contracts@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/contracts@npm:5.7.0" dependencies: @@ -3794,6 +3821,17 @@ __metadata: languageName: node linkType: hard +"@ethersproject/experimental@npm:^5.6.0": + version: 5.7.0 + resolution: "@ethersproject/experimental@npm:5.7.0" + dependencies: + "@ethersproject/web": ^5.7.0 + ethers: ^5.7.0 + scrypt-js: 3.0.1 + checksum: a4973371be9b984d5834df5d6fe3d4d1641204ec859a6d4e11e4a972a3a4a2dd7c0eae6a9a86b90f30faa3633a86ab153197bff6e853fb3ff8f847e0340a3c24 + languageName: node + linkType: hard + "@ethersproject/hash@npm:5.7.0, @ethersproject/hash@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/hash@npm:5.7.0" @@ -3852,7 +3890,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/keccak256@npm:5.7.0, @ethersproject/keccak256@npm:^5.7.0": +"@ethersproject/keccak256@npm:5.7.0, @ethersproject/keccak256@npm:^5.6.0, @ethersproject/keccak256@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/keccak256@npm:5.7.0" dependencies: @@ -3897,7 +3935,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/providers@npm:5.7.2, @ethersproject/providers@npm:^5.7.2": +"@ethersproject/providers@npm:5.7.2, @ethersproject/providers@npm:^5.6.0, @ethersproject/providers@npm:^5.7.2": version: 5.7.2 resolution: "@ethersproject/providers@npm:5.7.2" dependencies: @@ -3956,7 +3994,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/signing-key@npm:5.7.0, @ethersproject/signing-key@npm:^5.7.0": +"@ethersproject/signing-key@npm:5.7.0, @ethersproject/signing-key@npm:^5.6.0, @ethersproject/signing-key@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/signing-key@npm:5.7.0" dependencies: @@ -3970,7 +4008,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/solidity@npm:5.7.0, @ethersproject/solidity@npm:^5.0.0, @ethersproject/solidity@npm:^5.0.9, @ethersproject/solidity@npm:^5.7.0": +"@ethersproject/solidity@npm:5.7.0, @ethersproject/solidity@npm:^5.0.0, @ethersproject/solidity@npm:^5.0.9, @ethersproject/solidity@npm:^5.6.0, @ethersproject/solidity@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/solidity@npm:5.7.0" dependencies: @@ -3984,7 +4022,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/strings@npm:5.7.0, @ethersproject/strings@npm:^5.7.0": +"@ethersproject/strings@npm:5.7.0, @ethersproject/strings@npm:^5.6.0, @ethersproject/strings@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/strings@npm:5.7.0" dependencies: @@ -4012,7 +4050,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/units@npm:5.7.0, @ethersproject/units@npm:^5.7.0": +"@ethersproject/units@npm:5.7.0, @ethersproject/units@npm:^5.6.0, @ethersproject/units@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/units@npm:5.7.0" dependencies: @@ -4262,6 +4300,7 @@ __metadata: resolution: "@examples/imx-to-zkevm-migrator@workspace:examples/x-to-zkevm-migration-app/frontend" dependencies: "@biom3/react": ^0.27.25 + "@imtbl/imx-sdk": ^3.8.2 "@imtbl/sdk": ^1.52.0 "@types/node": ^20 "@types/react": ^18 @@ -4467,6 +4506,13 @@ __metadata: languageName: node linkType: hard +"@gamestopnft/detect-gamestop-provider@npm:^1.0.0": + version: 1.0.0 + resolution: "@gamestopnft/detect-gamestop-provider@npm:1.0.0" + checksum: 9d85a6e5c46e6e8a1107d88c8e92069d2e54ab37a9fc87f8f53d8ee11102254c064a7309fc3c3347c40e95cfb29ed9f5e83037636b92d7c9746f6f1965979ed0 + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.11.10": version: 0.11.10 resolution: "@humanwhocodes/config-array@npm:0.11.10" @@ -4916,6 +4962,56 @@ __metadata: languageName: node linkType: hard +"@imtbl/imx-sdk@npm:^3.8.2": + version: 3.8.2 + resolution: "@imtbl/imx-sdk@npm:3.8.2" + dependencies: + "@ethersproject/abstract-signer": ^5.6.0 + "@ethersproject/address": ^5.6.0 + "@ethersproject/bignumber": ^5.6.0 + "@ethersproject/bytes": ^5.6.0 + "@ethersproject/contracts": ^5.6.0 + "@ethersproject/experimental": ^5.6.0 + "@ethersproject/keccak256": ^5.6.0 + "@ethersproject/providers": ^5.6.0 + "@ethersproject/signing-key": ^5.6.0 + "@ethersproject/solidity": ^5.6.0 + "@ethersproject/strings": ^5.6.0 + "@ethersproject/units": ^5.6.0 + "@gamestopnft/detect-gamestop-provider": ^1.0.0 + auto-bind: ^4.0.0 + axios: ^0.21.1 + axios-retry: ^3.2.4 + bignumber.js: ^9.0.1 + bitwise: ^2.1.0 + bn.js: ^5.2.0 + colors: ^1.4.0 + elliptic: ^6.5.3 + enc-utils: ^3.0.0 + ethereumjs-wallet: ^1.0.1 + ethers: ^5.7.1 + fp-ts: 2.9.3 + fp-ts-std: ^0.5.2 + hash.js: ^1.1.7 + io-ts: 2.2.13 + io-ts-reporters: ^1.2.2 + io-ts-types: ^0.5.16 + magic-sdk: ^18.2.1 + moment: ^2.29.4 + monocle-ts: ^2.3.11 + newtype-ts: ^0.3.4 + node-fetch: ^2.6.11 + qs: ^6.10.1 + query-string: ^7.0.1 + rxjs: ^6.6.3 + soltypes: ^1.3.5 + winston: ^3.11.0 + ws: ^7.3.1 + yalc: ^1.0.0-pre.53 + checksum: feccb54305a4ca956a55e4e54d092aa12be927597b975fb19b7a6c41325f0793c17829756402d06213a72a770c5e01c4aeaf5562ddd5c7773e221ac0b53559d1 + languageName: node + linkType: hard + "@imtbl/metrics@0.0.0, @imtbl/metrics@workspace:packages/internal/metrics": version: 0.0.0-use.local resolution: "@imtbl/metrics@workspace:packages/internal/metrics" @@ -6875,6 +6971,16 @@ __metadata: languageName: node linkType: hard +"@magic-sdk/commons@npm:^14.6.0": + version: 14.6.0 + resolution: "@magic-sdk/commons@npm:14.6.0" + peerDependencies: + "@magic-sdk/provider": ">=4.3.0" + "@magic-sdk/types": ">=3.1.1" + checksum: 43c71771ddf3355d16fe1eed29d778cdb01b40b2af5f67a07173d0c41b3bc3f14a8513221948a84191805372b2d34f1097e8f0de771ed867c3485ffb1805dcd8 + languageName: node + linkType: hard + "@magic-sdk/commons@npm:^17.2.0": version: 17.2.0 resolution: "@magic-sdk/commons@npm:17.2.0" @@ -6885,6 +6991,19 @@ __metadata: languageName: node linkType: hard +"@magic-sdk/provider@npm:^18.6.0": + version: 18.6.0 + resolution: "@magic-sdk/provider@npm:18.6.0" + dependencies: + "@magic-sdk/types": ^15.8.0 + eventemitter3: ^4.0.4 + web3-core: 1.5.2 + peerDependencies: + localforage: ^1.7.4 + checksum: 11023862f112de99cebc1f1a234f2027c14007dc3bde0f8b3afd3ad78e4f402bc53a7797ef25fbd37017eda423df7c3d5193cd3f476c77dfe98eb2b7a3656400 + languageName: node + linkType: hard + "@magic-sdk/provider@npm:^21.2.0": version: 21.2.0 resolution: "@magic-sdk/provider@npm:21.2.0" @@ -6898,6 +7017,13 @@ __metadata: languageName: node linkType: hard +"@magic-sdk/types@npm:^15.8.0": + version: 15.8.0 + resolution: "@magic-sdk/types@npm:15.8.0" + checksum: aa719267f741cdb293b78541ebe0901eecf251b98e674484e73974b04f7433917006b675017f84537ce162957bfa16e3550423d5eeba05e0827aea694ca849b9 + languageName: node + linkType: hard + "@magic-sdk/types@npm:^17.2.0": version: 17.2.0 resolution: "@magic-sdk/types@npm:17.2.0" @@ -13638,6 +13764,13 @@ __metadata: languageName: node linkType: hard +"@types/triple-beam@npm:^1.3.2": + version: 1.3.5 + resolution: "@types/triple-beam@npm:1.3.5" + checksum: 519b6a1b30d4571965c9706ad5400a200b94e4050feca3e7856e3ea7ac00ec9903e32e9a10e2762d0f7e472d5d03e5f4b29c16c0bd8c1f77c8876c683b2231f1 + languageName: node + linkType: hard + "@types/trusted-types@npm:^2.0.2": version: 2.0.3 resolution: "@types/trusted-types@npm:2.0.3" @@ -16093,6 +16226,13 @@ __metadata: languageName: node linkType: hard +"auto-bind@npm:^4.0.0": + version: 4.0.0 + resolution: "auto-bind@npm:4.0.0" + checksum: 00cad71cce5742faccb7dd65c1b55ebc4f45add4b0c9a1547b10b05bab22813230133b0c892c67ba3eb969a4524710c5e43cc45c72898ec84e56f3a596e7a04f + languageName: node + linkType: hard + "autoprefixer@npm:10.4.14, autoprefixer@npm:^10.4.13": version: 10.4.14 resolution: "autoprefixer@npm:10.4.14" @@ -16169,6 +16309,16 @@ __metadata: languageName: node linkType: hard +"axios-retry@npm:^3.2.4": + version: 3.9.1 + resolution: "axios-retry@npm:3.9.1" + dependencies: + "@babel/runtime": ^7.15.4 + is-retry-allowed: ^2.2.0 + checksum: 44e574ad559e4ee638e735662e9b9fcb69a1da6652adc3a75ca4b060e0fd40bdd7ac718e7743f51c0dad54149a6f3c09109275bf90298042542e80a17740a4e5 + languageName: node + linkType: hard + "axios@npm:*": version: 1.4.0 resolution: "axios@npm:1.4.0" @@ -16191,7 +16341,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^0.21.2": +"axios@npm:^0.21.1, axios@npm:^0.21.2": version: 0.21.4 resolution: "axios@npm:0.21.4" dependencies: @@ -16780,6 +16930,13 @@ __metadata: languageName: node linkType: hard +"bitwise@npm:^2.1.0": + version: 2.2.1 + resolution: "bitwise@npm:2.2.1" + checksum: 7592fceb47fc9c2999a99cdf70b2adb23e4976b257fc2a166207e42bcaebcf60d4161cfb9b9afbe37d582376561b504e657b11fb165ad3ca68ef4be33239d435 + languageName: node + linkType: hard + "bl@npm:^4.0.3, bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" @@ -18115,7 +18272,7 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^1.9.0": +"color-convert@npm:^1.9.0, color-convert@npm:^1.9.3": version: 1.9.3 resolution: "color-convert@npm:1.9.3" dependencies: @@ -18140,13 +18297,23 @@ __metadata: languageName: node linkType: hard -"color-name@npm:~1.1.4": +"color-name@npm:^1.0.0, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 languageName: node linkType: hard +"color-string@npm:^1.6.0": + version: 1.9.1 + resolution: "color-string@npm:1.9.1" + dependencies: + color-name: ^1.0.0 + simple-swizzle: ^0.2.2 + checksum: c13fe7cff7885f603f49105827d621ce87f4571d78ba28ef4a3f1a104304748f620615e6bf065ecd2145d0d9dad83a3553f52bb25ede7239d18e9f81622f1cc5 + languageName: node + linkType: hard + "color-support@npm:^1.1.3": version: 1.1.3 resolution: "color-support@npm:1.1.3" @@ -18156,6 +18323,16 @@ __metadata: languageName: node linkType: hard +"color@npm:^3.1.3": + version: 3.2.1 + resolution: "color@npm:3.2.1" + dependencies: + color-convert: ^1.9.3 + color-string: ^1.6.0 + checksum: f81220e8b774d35865c2561be921f5652117638dcda7ca4029262046e37fc2444ac7bbfdd110cf1fd9c074a4ee5eda8f85944ffbdda26186b602dd9bb05f6400 + languageName: node + linkType: hard + "colord@npm:^2.9.1": version: 2.9.3 resolution: "colord@npm:2.9.3" @@ -18170,13 +18347,23 @@ __metadata: languageName: node linkType: hard -"colors@npm:1.4.0, colors@npm:^1.1.2": +"colors@npm:1.4.0, colors@npm:^1.1.2, colors@npm:^1.4.0": version: 1.4.0 resolution: "colors@npm:1.4.0" checksum: 98aa2c2418ad87dedf25d781be69dc5fc5908e279d9d30c34d8b702e586a0474605b3a189511482b9d5ed0d20c867515d22749537f7bc546256c6014f3ebdcec languageName: node linkType: hard +"colorspace@npm:1.1.x": + version: 1.1.4 + resolution: "colorspace@npm:1.1.4" + dependencies: + color: ^3.1.3 + text-hex: 1.0.x + checksum: bb3934ef3c417e961e6d03d7ca60ea6e175947029bfadfcdb65109b01881a1c0ecf9c2b0b59abcd0ee4a0d7c1eae93beed01b0e65848936472270a0b341ebce8 + languageName: node + linkType: hard + "combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" @@ -20422,6 +20609,13 @@ __metadata: languageName: node linkType: hard +"enabled@npm:2.0.x": + version: 2.0.0 + resolution: "enabled@npm:2.0.0" + checksum: 9d256d89f4e8a46ff988c6a79b22fa814b4ffd82826c4fdacd9b42e9b9465709d3b748866d0ab4d442dfc6002d81de7f7b384146ccd1681f6a7f868d2acca063 + languageName: node + linkType: hard + "enc-utils@npm:^3.0.0": version: 3.0.0 resolution: "enc-utils@npm:3.0.0" @@ -22007,7 +22201,7 @@ __metadata: languageName: node linkType: hard -"ethereumjs-wallet@npm:^1.0.2": +"ethereumjs-wallet@npm:^1.0.1, ethereumjs-wallet@npm:^1.0.2": version: 1.0.2 resolution: "ethereumjs-wallet@npm:1.0.2" dependencies: @@ -22074,7 +22268,7 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^5.5.3, ethers@npm:^5.7.0, ethers@npm:^5.7.2": +"ethers@npm:^5.5.3, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": version: 5.7.2 resolution: "ethers@npm:5.7.2" dependencies: @@ -22763,6 +22957,13 @@ __metadata: languageName: node linkType: hard +"fecha@npm:^4.2.0": + version: 4.2.3 + resolution: "fecha@npm:4.2.3" + checksum: f94e2fb3acf5a7754165d04549460d3ae6c34830394d20c552197e3e000035d69732d74af04b9bed3283bf29fe2a9ebdcc0085e640b0be3cc3658b9726265e31 + languageName: node + linkType: hard + "fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": version: 3.2.0 resolution: "fetch-blob@npm:3.2.0" @@ -23012,6 +23213,13 @@ __metadata: languageName: node linkType: hard +"fn.name@npm:1.x.x": + version: 1.1.0 + resolution: "fn.name@npm:1.1.0" + checksum: e357144f48cfc9a7f52a82bbc6c23df7c8de639fce049cac41d41d62cabb740cdb9f14eddc6485e29c933104455bdd7a69bb14a9012cef9cd4fa252a4d0cf293 + languageName: node + linkType: hard + "follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0": version: 1.15.2 resolution: "follow-redirects@npm:1.15.2" @@ -23172,6 +23380,17 @@ __metadata: languageName: node linkType: hard +"fp-ts-std@npm:^0.5.2": + version: 0.5.2 + resolution: "fp-ts-std@npm:0.5.2" + peerDependencies: + fp-ts: ^2.0.0 + monocle-ts: ^2.0.0 + newtype-ts: ^0.3.0 + checksum: 351ef73a29d6015427c6915723f49a6824a914ad2f07c48eec5fd22b143cdaae496d3846d35cfc439942a0d761be036b039ba260727420ff0733358d021138a7 + languageName: node + linkType: hard + "fp-ts@npm:1.19.3": version: 1.19.3 resolution: "fp-ts@npm:1.19.3" @@ -23179,6 +23398,13 @@ __metadata: languageName: node linkType: hard +"fp-ts@npm:2.9.3": + version: 2.9.3 + resolution: "fp-ts@npm:2.9.3" + checksum: b269c31360d6b38c37bc8f113e7e0d32eda02281baadb3cdaf3ab36a39074f07fc72418efcb5efa9b817356f735feee0583b99ebde3dbe73cf4ea683654df5cc + languageName: node + linkType: hard + "fp-ts@npm:^1.0.0": version: 1.19.5 resolution: "fp-ts@npm:1.19.5" @@ -23297,7 +23523,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^8.1.0": +"fs-extra@npm:^8.0.1, fs-extra@npm:^8.1.0": version: 8.1.0 resolution: "fs-extra@npm:8.1.0" dependencies: @@ -25025,6 +25251,15 @@ __metadata: languageName: node linkType: hard +"ignore-walk@npm:^3.0.3": + version: 3.0.4 + resolution: "ignore-walk@npm:3.0.4" + dependencies: + minimatch: ^3.0.4 + checksum: 9e9c5ef6c3e0ed7ef5d797991abb554dbb7e60d5fedf6cf05c7129819689eba2b462f625c6e3561e0fc79841904eb829565513eeeab1b44f4fbec4d3146b1a8d + languageName: node + linkType: hard + "ignore@npm:^5.0.4, ignore@npm:^5.1.1": version: 5.3.1 resolution: "ignore@npm:5.3.1" @@ -25134,7 +25369,7 @@ __metadata: languageName: node linkType: hard -"ini@npm:2.0.0": +"ini@npm:2.0.0, ini@npm:^2.0.0": version: 2.0.0 resolution: "ini@npm:2.0.0" checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e @@ -25255,6 +25490,28 @@ __metadata: languageName: node linkType: hard +"io-ts-reporters@npm:^1.2.2": + version: 1.2.2 + resolution: "io-ts-reporters@npm:1.2.2" + peerDependencies: + fp-ts: ^2.0.2 + io-ts: ^2.0.0 + checksum: 50dd159570ec4cee07ae07c138674163aab51ef64866078cbf16af7880d2ded53005b4b42e49ff13edb4f45adc8d924bdf342d3c291700e9e33acedd0fde7926 + languageName: node + linkType: hard + +"io-ts-types@npm:^0.5.16": + version: 0.5.19 + resolution: "io-ts-types@npm:0.5.19" + peerDependencies: + fp-ts: ^2.0.0 + io-ts: ^2.0.0 + monocle-ts: ^2.0.0 + newtype-ts: ^0.3.2 + checksum: 4cf8688b9fd3878bebc332f9cdf612e72ce45bcc8ab4a534d413a4f80564458482bc1c86eed997ca566e65ac85790d3c7a8ccb511f8c17108cd647e070db7790 + languageName: node + linkType: hard + "io-ts@npm:1.10.4": version: 1.10.4 resolution: "io-ts@npm:1.10.4" @@ -25264,6 +25521,15 @@ __metadata: languageName: node linkType: hard +"io-ts@npm:2.2.13": + version: 2.2.13 + resolution: "io-ts@npm:2.2.13" + peerDependencies: + fp-ts: ^2.0.0 + checksum: 611025826be34be173be0a0f11be4379f845854e577e09498b6574ad72302fd1da118e30741e119d4b44735efe833b4b9cfd9e6762bfc81117201a819f5831ab + languageName: node + linkType: hard + "ioredis@npm:^5.3.2": version: 5.3.2 resolution: "ioredis@npm:5.3.2" @@ -25363,6 +25629,13 @@ __metadata: languageName: node linkType: hard +"is-arrayish@npm:^0.3.1": + version: 0.3.2 + resolution: "is-arrayish@npm:0.3.2" + checksum: 977e64f54d91c8f169b59afcd80ff19227e9f5c791fa28fa2e5bce355cbaf6c2c356711b734656e80c9dd4a854dd7efcf7894402f1031dfc5de5d620775b4d5f + languageName: node + linkType: hard + "is-async-function@npm:^2.0.0": version: 2.0.0 resolution: "is-async-function@npm:2.0.0" @@ -25837,6 +26110,13 @@ __metadata: languageName: node linkType: hard +"is-retry-allowed@npm:^2.2.0": + version: 2.2.0 + resolution: "is-retry-allowed@npm:2.2.0" + checksum: 3d1103a9290b5d03626756a41054844633eac78bc5d3e3a95b13afeae94fa3cfbcf7f0b5520d83f75f48a25ce7b142fdbac4217dc4b0630f3ea55e866ec3a029 + languageName: node + linkType: hard + "is-root@npm:^2.1.0": version: 2.1.0 resolution: "is-root@npm:2.1.0" @@ -28656,6 +28936,13 @@ __metadata: languageName: node linkType: hard +"kuler@npm:^2.0.0": + version: 2.0.0 + resolution: "kuler@npm:2.0.0" + checksum: 9e10b5a1659f9ed8761d38df3c35effabffbd19fc6107324095238e4ef0ff044392cae9ac64a1c2dda26e532426485342226b93806bd97504b174b0dcf04ed81 + languageName: node + linkType: hard + "language-subtag-registry@npm:^0.3.20": version: 0.3.23 resolution: "language-subtag-registry@npm:0.3.23" @@ -29303,6 +29590,20 @@ __metadata: languageName: node linkType: hard +"logform@npm:^2.7.0": + version: 2.7.0 + resolution: "logform@npm:2.7.0" + dependencies: + "@colors/colors": 1.6.0 + "@types/triple-beam": ^1.3.2 + fecha: ^4.2.0 + ms: ^2.1.1 + safe-stable-stringify: ^2.3.1 + triple-beam: ^1.3.0 + checksum: a202d10897254735ead75a640f889998f9b91a0c36be9cac3f5471fa740d36bc2fbbcf9d113dcdadec4ddf09e257393ff800e6aab80019bdc7456363d6ea21f6 + languageName: node + linkType: hard + "long@npm:^4.0.0": version: 4.0.0 resolution: "long@npm:4.0.0" @@ -29471,6 +29772,18 @@ __metadata: languageName: node linkType: hard +"magic-sdk@npm:^18.2.1": + version: 18.6.0 + resolution: "magic-sdk@npm:18.6.0" + dependencies: + "@magic-sdk/commons": ^14.6.0 + "@magic-sdk/provider": ^18.6.0 + "@magic-sdk/types": ^15.8.0 + localforage: ^1.7.4 + checksum: 22d540a5b25e767c8d063c08e7b532daa4eb72d397c5a6b10b2060d2b5261d559a2ca30186c780f65f2f4a4fffc0c22774b8fca977e4ebf1c210a56329e2e06d + languageName: node + linkType: hard + "magic-sdk@npm:^21.2.0": version: 21.2.0 resolution: "magic-sdk@npm:21.2.0" @@ -30139,6 +30452,22 @@ __metadata: languageName: node linkType: hard +"moment@npm:^2.29.4": + version: 2.30.1 + resolution: "moment@npm:2.30.1" + checksum: 859236bab1e88c3e5802afcf797fc801acdbd0ee509d34ea3df6eea21eb6bcc2abd4ae4e4e64aa7c986aa6cba563c6e62806218e6412a765010712e5fa121ba6 + languageName: node + linkType: hard + +"monocle-ts@npm:^2.3.11": + version: 2.3.13 + resolution: "monocle-ts@npm:2.3.13" + peerDependencies: + fp-ts: ^2.5.0 + checksum: dddfa5706fe1fdb068606f5ac5215a00e723d155407de491bb53591264e281ec0ea1735759db93686d9daf676b105660bf2c656ebcd51626a4bfbb8de9accb3c + languageName: node + linkType: hard + "motion@npm:10.16.2": version: 10.16.2 resolution: "motion@npm:10.16.2" @@ -30420,6 +30749,16 @@ __metadata: languageName: node linkType: hard +"newtype-ts@npm:^0.3.4": + version: 0.3.5 + resolution: "newtype-ts@npm:0.3.5" + peerDependencies: + fp-ts: ^2.0.0 + monocle-ts: ^2.0.0 + checksum: 3168c0386313156f4ecf9160eec48d5506aa372d3406f6a05fde9f75b8f9549b149dea53574e9b2f201190c01fe49af8c9554481b319f0b616a4413f89af3d16 + languageName: node + linkType: hard + "next-tick@npm:^1.1.0": version: 1.1.0 resolution: "next-tick@npm:1.1.0" @@ -30708,7 +31047,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.1, node-fetch@npm:^2.7.0": +"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.11, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -30963,6 +31302,36 @@ __metadata: languageName: node linkType: hard +"npm-bundled@npm:^1.1.1": + version: 1.1.2 + resolution: "npm-bundled@npm:1.1.2" + dependencies: + npm-normalize-package-bin: ^1.0.1 + checksum: 6e599155ef28d0b498622f47f1ba189dfbae05095a1ed17cb3a5babf961e965dd5eab621f0ec6f0a98de774e5836b8f5a5ee639010d64f42850a74acec3d4d09 + languageName: node + linkType: hard + +"npm-normalize-package-bin@npm:^1.0.1": + version: 1.0.1 + resolution: "npm-normalize-package-bin@npm:1.0.1" + checksum: ae7f15155a1e3ace2653f12ddd1ee8eaa3c84452fdfbf2f1943e1de264e4b079c86645e2c55931a51a0a498cba31f70022a5219d5665fbcb221e99e58bc70122 + languageName: node + linkType: hard + +"npm-packlist@npm:^2.1.5": + version: 2.2.2 + resolution: "npm-packlist@npm:2.2.2" + dependencies: + glob: ^7.1.6 + ignore-walk: ^3.0.3 + npm-bundled: ^1.1.1 + npm-normalize-package-bin: ^1.0.1 + bin: + npm-packlist: bin/index.js + checksum: 799ce94b077e4dc366a9a5bcc5f006669263bb1a48d6948161aed915fd2f11dea8a7cf516a63fc78e5df059915591dade5928f0738baadc99a8ab4685d8b58c3 + languageName: node + linkType: hard + "npm-run-path@npm:^2.0.0": version: 2.0.2 resolution: "npm-run-path@npm:2.0.2" @@ -31435,6 +31804,15 @@ __metadata: languageName: node linkType: hard +"one-time@npm:^1.0.0": + version: 1.0.0 + resolution: "one-time@npm:1.0.0" + dependencies: + fn.name: 1.x.x + checksum: fd008d7e992bdec1c67f53a2f9b46381ee12a9b8c309f88b21f0223546003fb47e8ad7c1fd5843751920a8d276c63bd4b45670ef80c61fb3e07dbccc962b5c7d + languageName: node + linkType: hard + "onetime@npm:^5.1.0, onetime@npm:^5.1.2": version: 5.1.2 resolution: "onetime@npm:5.1.2" @@ -34026,6 +34404,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.10.1": + version: 6.13.1 + resolution: "qs@npm:6.13.1" + dependencies: + side-channel: ^1.0.6 + checksum: 86c5059146955fab76624e95771031541328c171b1d63d48a7ac3b1fdffe262faf8bc5fcadc1684e6f3da3ec87a8dedc8c0009792aceb20c5e94dc34cf468bb9 + languageName: node + linkType: hard + "qs@npm:^6.11.0, qs@npm:^6.4.0": version: 6.11.2 resolution: "qs@npm:6.11.2" @@ -34035,7 +34422,7 @@ __metadata: languageName: node linkType: hard -"query-string@npm:7.1.3": +"query-string@npm:7.1.3, query-string@npm:^7.0.1": version: 7.1.3 resolution: "query-string@npm:7.1.3" dependencies: @@ -36448,6 +36835,15 @@ __metadata: languageName: node linkType: hard +"simple-swizzle@npm:^0.2.2": + version: 0.2.2 + resolution: "simple-swizzle@npm:0.2.2" + dependencies: + is-arrayish: ^0.3.1 + checksum: a7f3f2ab5c76c4472d5c578df892e857323e452d9f392e1b5cf74b74db66e6294a1e1b8b390b519fa1b96b5b613f2a37db6cffef52c3f1f8f3c5ea64eb2d54c0 + languageName: node + linkType: hard + "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" @@ -36705,6 +37101,16 @@ __metadata: languageName: node linkType: hard +"soltypes@npm:^1.3.5": + version: 1.3.5 + resolution: "soltypes@npm:1.3.5" + dependencies: + bn.js: ^5.1.2 + js-sha3: ^0.8.0 + checksum: 77ea9f9084121bff26a7bae78b08829a074d43795905c2f8ba6e7620f984184053563a6ecb0270ed25001dd504f6555ebdd2633ba551040b8e00e48e4e0f453b + languageName: node + linkType: hard + "sonic-boom@npm:^2.2.1": version: 2.8.0 resolution: "sonic-boom@npm:2.8.0" @@ -37048,6 +37454,13 @@ __metadata: languageName: node linkType: hard +"stack-trace@npm:0.0.x": + version: 0.0.10 + resolution: "stack-trace@npm:0.0.10" + checksum: 473036ad32f8c00e889613153d6454f9be0536d430eb2358ca51cad6b95cea08a3cc33cc0e34de66b0dad221582b08ed2e61ef8e13f4087ab690f388362d6610 + languageName: node + linkType: hard + "stack-utils@npm:^2.0.2, stack-utils@npm:^2.0.3": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" @@ -38243,6 +38656,13 @@ __metadata: languageName: node linkType: hard +"text-hex@npm:1.0.x": + version: 1.0.0 + resolution: "text-hex@npm:1.0.0" + checksum: 1138f68adc97bf4381a302a24e2352f04992b7b1316c5003767e9b0d3367ffd0dc73d65001ea02b07cd0ecc2a9d186de0cf02f3c2d880b8a522d4ccb9342244a + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -38586,6 +39006,13 @@ __metadata: languageName: node linkType: hard +"triple-beam@npm:^1.3.0": + version: 1.4.1 + resolution: "triple-beam@npm:1.4.1" + checksum: 2e881a3e8e076b6f2b85b9ec9dd4a900d3f5016e6d21183ed98e78f9abcc0149e7d54d79a3f432b23afde46b0885bdcdcbff789f39bc75de796316961ec07f61 + languageName: node + linkType: hard + "tryer@npm:^1.0.1": version: 1.0.1 resolution: "tryer@npm:1.0.1" @@ -40957,6 +41384,36 @@ __metadata: languageName: node linkType: hard +"winston-transport@npm:^4.9.0": + version: 4.9.0 + resolution: "winston-transport@npm:4.9.0" + dependencies: + logform: ^2.7.0 + readable-stream: ^3.6.2 + triple-beam: ^1.3.0 + checksum: f5fd06a27def7597229925ba2b8b9ffa61b5b8748f994c8325064744e4e36dfea19868a16c16b3806f9b98bb7da67c25f08ae6fba3bdc6db4a9555673474a972 + languageName: node + linkType: hard + +"winston@npm:^3.11.0": + version: 3.17.0 + resolution: "winston@npm:3.17.0" + dependencies: + "@colors/colors": ^1.6.0 + "@dabh/diagnostics": ^2.0.2 + async: ^3.2.3 + is-stream: ^2.0.0 + logform: ^2.7.0 + one-time: ^1.0.0 + readable-stream: ^3.4.0 + safe-stable-stringify: ^2.3.1 + stack-trace: 0.0.x + triple-beam: ^1.3.0 + winston-transport: ^4.9.0 + checksum: ba772c25937007cea6cdeddc931de18a1ea336ae7b3aff2c15de762de5c559b2d310ca2e7a911c209711d325e47d653485e33271ddfb27cd73179e35c7d52267 + languageName: node + linkType: hard + "word-wrap@npm:~1.2.3": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -41311,7 +41768,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7": +"ws@npm:^7, ws@npm:^7.3.1": version: 7.5.10 resolution: "ws@npm:7.5.10" peerDependencies: @@ -41528,6 +41985,24 @@ __metadata: languageName: node linkType: hard +"yalc@npm:^1.0.0-pre.53": + version: 1.0.0-pre.53 + resolution: "yalc@npm:1.0.0-pre.53" + dependencies: + chalk: ^4.1.0 + detect-indent: ^6.0.0 + fs-extra: ^8.0.1 + glob: ^7.1.4 + ignore: ^5.0.4 + ini: ^2.0.0 + npm-packlist: ^2.1.5 + yargs: ^16.1.1 + bin: + yalc: src/yalc.js + checksum: 3421e20039909fd0497e43ec05278e9f661d2300506deeaf06d8698e2f4dd37f905a267e85ec51e29811fd3d3844051172f4bb31049113774d502a69b0ecf2a1 + languageName: node + linkType: hard + "yallist@npm:^2.1.2": version: 2.1.2 resolution: "yallist@npm:2.1.2" @@ -41655,7 +42130,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^16.2.0": +"yargs@npm:^16.1.1, yargs@npm:^16.2.0": version: 16.2.0 resolution: "yargs@npm:16.2.0" dependencies: