- Forging
- Feature
- Usage
Forging is a convenient and developer-friendly Web3 wallet toolkit that supports generating, importing, and exporting both single and batch HD and non-HD wallets.
Built with a modular, pluggable architecture, it allows seamless extension to any chain and ships with first-class support for Solana and all EVM-compatible chains (Ethereum, BNB Chain, Polygon, Arbitrum, etc.).
-
Generate single or batch HD/Non-HD wallets for any specific chain with one click.
-
Import single or batch HD/non-HD wallets for any specific chain with one click.
-
Export single or batch HD/Non-HD wallets for any specific chain with one click.
-
Generate single or batch HD/non-HD wallets across multiple chains with one click.
-
Import single or batch HD/non-HD wallets across multiple chains with one click.
.package(url: "https://https://github.com/BCSuite/Forging.git", from: "0.0.1")
-
Single chain.
-
Single wallet
// Solana. let generator = FGNonHDWalletUniGenerator.solana() let wallet = try generator.generate() print("address:\(wallet.address), privKey:\(wallet.privKey)") // EVM. let generator = FGNonHDWalletUniGenerator.evm() let wallet = try generator.generate() print("address:\(wallet.address), privKey:\(wallet.privKey)" -
batch wallets
// Solana. let genCnt = 201 let generator = FGNonHDWalletUniGenerator.solana() let wallets = try await generator.batchGenerate(inCount: genCnt) for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey)") } // EVM. let genCnt = 101 let generator = FGNonHDWalletUniGenerator.evm() let wallets = try await generator.batchGenerate(inCount: genCnt) for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey)") }The
batchGeneratewill ignoring failed cases and continue generating by default. If want to stop once any generation fails, set theisInterruptibleparam totrue.let wallets = try await generator.batchGenerate(inCount: genCnt, isInterruptible: true)
-
-
Multi-chain.
-
Single wallet
// Set up all needed EVM chains except Ethereum which will be contained by default. let evmSharedChains: [any FGChainDescribable.Type] = [FGBaseChain.self, FGOptimismChain.self] // Configure the generation handler of each chain. let handlers = [FGNonHDGenHandler.solana(), FGNonHDGenHandler.evm(serviceSharedChains: evmSharedChains)] // Create a multi-chain tasks processor. let generator = FGMultiChainWalletProcessor(chainHandlers: handlers) // Generate with the operation kind: FGMultiChainNonHDWalletGenKind. let walletMap = try await generator.process(with: .single) for (chainName, wallets) in walletMap { // Wallets only contains one wallet. print("\(chainName)->wallet\(String(describing: wallets.first))") } /// Output /// Optimism->wallet: Optional(Forging.FGCryptoWallet(address: "0x1..6”, privKey: “d….9”, mnemonic: nil)) Solana->Optional(Forging.FGCryptoWallet(address: "GF..JoK", privKey: "59E..”, mnemonic: nil)) Ethereum-> Optional(Forging.FGCryptoWallet(address: "0x1..b”, privKey: “d..9”, mnemonic: nil)) Base -> Optional(Forging.FGCryptoWallet(address: "0x1..b”, privKey: “d..9”, mnemonic: nil) -
batch wallets
let genCnt = 20 // Set up all needed EVM chains except Ethereum which will be contained by default. let evmSharedChains: [any FGChainDescribable.Type] = [FGBaseChain.self, FGOptimismChain.self] // Configure the generation handler of each chain. let handlers = [FGNonHDGenHandler.solana(), FGNonHDGenHandler.evm(serviceSharedChains: evmSharedChains)] // Create a multi-chain tasks processor. let generator = FGMultiChainWalletProcessor(chainHandlers: handlers) // Generate with the operation kind of FGMultiChainNonHDWalletGenKind.batch(count:). let walletMap = try await generator.process(with: .batch(count: genCnt)) for (chainName, wallets) in walletMap { print("\(chainName):") for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey)") } } /// Output /// Optimism: address:0x1…1, privKey:9…8 address:0x2…5, privKey:7...c address:0xf..9, privKey:c..5 Ethereum: address:0x1…1, privKey:9…8 address:0x2..5, privKey:7..c address:0xf..9, privKey:c..5 Base: address:0x1…1, privKey:9…8 address:0x2..5, privKey:7..c address:0xf..9, privKey:c..5 Solana: address:A…k, privKey:5…a address:D…s, privKey:3…s address:G…5, privKey:M…u
-
-
Solana
let importer = FGSingleSolNonHDWalletImporter() let privKey = "y..a" let wallet = try importer.importWallet(from: privKey) print("address:\(wallet.address)") -
EVM
let importer = FGSingleEVMNonHDWalletImporter() let privKey = "a..n" let importedWallet = try importer.importWallet(from: wallet.privKey) print("address:\(wallet.address)")
-
Single chain
-
Single wallet
/// Solana /// // Generate a random Solana wallet with 12 words mnemonic. let generator = FGHDWalletUniGenerator.solana() let wallet = try generator.generate() print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic ?? "")") // Specify the mnemonic words count. // - 12 words(default): FGMnemonic12WordsSize // - 15 words: FGMnemonic15WordsSize // - 18 words: FGMnemonic18WordsSize // - 21 words: FGMnemonic21WordsSize // - 24 words: FGMnemonic24WordsSize let generator = FGHDWalletUniGenerator.solana() let mnemonicSize = FGMnemonic24WordsSize.self // or other size. let wallet = try generator.generate(atSize: mnemonicSize) print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic ?? "")") // Generate a Solana wallet from a given mnemonic. let generator = FGHDWalletUniGenerator.solana() let mnemonic = "xx xx..." let wallet = try generator.generate(from: mnemonic) print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic ?? "")") /// EVM /// // Gereate a random EVM wallet with 12 words mnemonic. let generator = FGHDWalletUniGenerator.evm() let wallet = try generator.generate() // Generate a EVM wallet from a given mnemonic. let generator = FGHDWalletUniGenerator.evm() let mnemonic = "xx xx..." let wallet = try generator.generate(from: mnemonic) -
Batch wallets
/// Solana /// let genCnt = 1000 let generator = FGHDWalletUniGenerator.solana() // Randomly generate Solana wallets with 12 words mnemonic. let wallets = try await generator.batchGenerate(inCount: genCnt) // Specify the mnemonic words count(default is 12 words). let mnemonicSize = let wallets = try await generator.batchGenerate(inCount: genCnt, mnemonicSize: FGMnemonic24WordsSize.self) // Generate Solana wallets given mnemonics. let mnemonics = ["xx", "yy"] let wallets = try await generator.batchGenerate(from: mnemonics) /// EVM /// let generator = FGHDWalletUniGenerator.evm() // Randomly generate EVM wallets with 12 words mnemonic. let wallets = try await generator.batchGenerate(inCount: genCnt) // Specify the mnemonic words count(default is 12 words). let mnemonicSize = let wallets = try await generator.batchGenerate(inCount: genCnt, mnemonicSize: FGMnemonic24WordsSize.self) // Generate EVM wallets given mnemonics. let mnemonics = ["xx", "yy"] let wallets = try await generator.batchGenerate(from: mnemonics)
-
-
Multi-chain
-
Single wallet
// Set up all needed EVM chains except Ethereum which will be contained by default. let evmSharedChains: [any FGChainDescribable.Type] = [FGBaseChain.self, FGOptimismChain.self] // Configure all handlers to generate wallets for the corresponding chains. let handlers = [FGHDGenHandler.solana(), FGHDGenHandler.evm(serviceSharedChains: evmSharedChains)] // Create a multi-chain tasks processor. let generator = FGMultiChainWalletProcessor(chainHandlers: handlers) // Generate with the operation kind: FGMultiChainHDWalletGenKind. // - singleRandom(mnemonicSize:): Generate a single wallet by generating random mnemomic for each chain. // - singleSpecific(mnemomic:): Generate a single wallet by using a given mnemomic for each chain // - batchRandom(count:, mnemonicSize:, isInterruptible:): Generate the specific count of // wallets by using random mnemomics for each chain. // - batchSpecific(mnemomics:, isInterruptible:): Generate the specific count of wallets by using the given mnemomics for each chain. let walletMap = try await generator.process(with: .singleRandom()) for (chainName, wallets) in walletMap { print("\(chainName):") for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic)") } } /// Output /// Optimism: address:0x1…1, privKey:9…8 Ethereum: address:0x1…1, privKey:9…8 Base: address:0x1…1, privKey:9…8 Solana: address:A…k, privKey:5…a -
Batch wallets
// Set up all needed EVM chains except Ethereum which will be contained by default. let evmSharedChains: [any FGChainDescribable.Type] = [FGBaseChain.self, FGOptimismChain.self] // Configure all handlers to generate wallets for the corresponding chains. let handlers = [FGNonHDGenHandler.solana(), FGNonHDGenHandler.evm(serviceSharedChains: evmSharedChains)] // Create a multi-chain tasks processor. let generator = FGMultiChainWalletProcessor(chainHandlers: handlers) let genCnt = 3 // Use the operation kind of .batch(count:). let walletMap = try await generator.process(with: .batch(count: genCnt)) for (chainName, wallets) in walletMap { print("\(chainName):") for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic)") } } /// Output /// Optimism: address:0x1…1, privKey:9…8 address:0x2…5, privKey:7...c address:0xf..9, privKey:c..5 Ethereum: address:0x1…1, privKey:9…8 address:0x2..5, privKey:7..c address:0xf..9, privKey:c..5 Base: address:0x1…1, privKey:9…8 address:0x2..5, privKey:7..c address:0xf..9, privKey:c..5 Solana: address:A…k, privKey:5…a address:D…s, privKey:3…s address:G…5, privKey:M…u
-
-
Single chain
-
Single wallet
/// Solana let importer = FGHDWalletUniGenerator.solana() let importedWallet = try importer.importWallet(from: wallet.mnemonic ?? "") /// EVM let importer = FGHDWalletUniGenerator.evm() let importedWallet = try importer.importWallet(from: wallet.mnemonic ?? "") -
Batch wallets
/// Solana let importer = FGHDWalletUniGenerator.evm() let importedWallet = try importer.importWallets(from: wallet.mnemonic ?? "") /// EVM let importer = FGHDWalletUniImporter.evm() let importedWalltes = try await importer.importWallets(from: phrases)
-
-
Multi-chain
-
Single wallet
// Set up all needed EVM chains except Ethereum which will be contained by default. let evmSharedChains: [any FGChainDescribable.Type] = [FGBaseChain.self, FGOptimismChain.self] // Configure the importing handler of each chain. let handlers = [FGHDImportHandler.solana(), FGHDImportHandler.evm(serviceSharedChains: evmSharedChains)] let importer = FGMultiChainWalletProcessor(chainHandlers: handlers) let mnemomic = "xx yy cc ..." // Using single(mnemonic:) as the import operation kind. let genWalletsMap = try await importer.process(with: .singleSpecific(mnemomic: mnemomic)) for (chainName, wallets) in walletMap { print("\(chainName):") for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic)") } } /// Output /// Optimism: address:0x1…1, privKey:9…8 Ethereum: address:0x1…1, privKey:9…8 Base: address:0x1…1, privKey:9…8 Solana: address:A…k, privKey:5…a -
Batch wallets
// Set up all needed EVM chains except Ethereum which will be contained by default. let evmSharedChains: [any FGChainDescribable.Type] = [FGBaseChain.self, FGOptimismChain.self] // Configure the importing handler of each chain. let handlers = [FGHDImportHandler.solana(), FGHDImportHandler.evm(serviceSharedChains: evmSharedChains)] let importer = FGMultiChainWalletProcessor(chainHandlers: handlers) let mnemonics = ["mnemonic1", "mnemonic2", ... ,"mnemonicN"] // Using single(mnemonic:) as the import operation kind. let genWalletsMap = try await importer.process(with: .batch(mnemonics: mnemonics)) for (chainName, wallets) in walletMap { print("\(chainName):") for wallet in wallets { print("address:\(wallet.address), privKey:\(wallet.privKey), mnemonic:\(wallet.mnemonic)") } }
-
-
Pasteboard
-
Single wallet
let importer = FGPasteboardExporter() let result = try await importer.export(wallet: wallet) if !result { // Execute the failure logic. } -
Batch wallets
let importer = FGPasteboardExporter() let result = try await importer.export(wallets: wallets) if !result { // Execute the failure logic. }Now, the FGPasteboardExporter only supports export 200 wallets and will throw a error if exceeds 200.
-
-
File
// Not sepecify the file path to export. Internally will create automaticlly a file in the //'Wallet_yyyyMMdd_HHmmss' name format if not set. let exporter = FGFileExporter() let isSuccess = try await exporter.export(wallet: wallet) // Sepecify the file path to export. let filePath = "A detailed path" let exporter = FGFileExporter(filePath: filePath) let isSuccess = try await exporter.export(wallet: wallet)The default max count of wallets that can be written at once is 100, if the total count of wallets to be exported exceeds this value, they will be written one by one, otherwise will be written in one time. It supports be sepecified by set the Initialization param
singleWriteMaxCount, but should set a reasonable value to avoid OOM.let exporter = FGFileExporter(singleWriteMaxCount: 500)