How to add deterministic wallet to launchTestNode

The launchTestNode() capability is great.

It would be awesome if we could pass a deterministic wallet to it so that a developer can easily dev against a dapp using the wallet in the fuel wallet.

Basically currently the developer needs to export and import the private key of each generated wallet each time the node is restarted.

Or am I missing something here?

Current code:

import { SRC721ContractAbi__factory } from "./types/factories/SRC721ContractAbi__factory";
import bytecode from "./types/SRC721ContractAbi.hex";

import { launchTestNode, AssetId, TestMessage } from "fuels/test-utils";

(async () => {
  try {
    // Define the assets and initial messages
    const assets = AssetId.random(2);
    const message = new TestMessage({ amount: 1000 });

    // Launch the test node with predefined configuration
    const launched = await launchTestNode({
      walletsConfig: {
        count: 4, // Number of wallets to create
        assets, // Assets to use
        coinsPerAsset: 2, // Number of coins per asset
        amountPerCoin: 1_000_000, // Amount per coin
        messages: [message], // Initial messages
      },
      contractsConfigs: [
        {
          deployer: SRC721ContractAbi__factory, // Contract deployer factory
          bytecode, // Contract bytecode
          walletIndex: 3, // Index of the wallet to deploy the contract
          options: { storageSlots: [] }, // Storage options for the contract
        },
      ],
    });

    // Destructure the launched object to get wallets and contracts
    const {
      contracts: [contract],
      wallets: [wallet1, wallet2, wallet3, wallet4],
    } = launched;

    console.log("Launched node with contracts and wallets");
    console.log({ contract, wallet1, wallet2, wallet3, wallet4 });
  } catch (e) {
    console.error(e);
  }
})();

1 Like

Same goes for being able to provide a fixed port for the node so that it doesn’t need to be readded as a new network.

@xpluscal The launchTestNode utility is intended for writing self-contained tests and isn’t intended to be used for dapp development but for writing tests for the dapp logic.

You should use the fuels cli for dapp development which should contain all the capabilities you ask for. I highly suggest you go through the creating a fuel dapp tutorial to see how to use the sdk in a holistic manner. The tutorial unfortunately doesn’t have an example of launchTestNode usage, but I see that you’ve already understood its API. To see launchTestNode usage in tests, you can see the advanced example’s source code here.

1 Like

@nedsalk thank you for the reply.

That is exactly my point though, from what I see the tutorial covers only how to deploy the contract on testnet to test it with the dapp.

What I’d like to do is fully integrated e2e from contract dev to dapp testing on a localnode.

I’ve used the advanced example for launchTestNode, and now I’d like to add a wallet to my localTestNode so that I don’t have to re-add a new wallet to Fuel Wallet everytime I run the node again.

I could run forc wallet account new with a node URL param to add my wallet to my testnode I suppose? Is there a way to use the same Mnemnonic to ensure its the same wallet each time?

It would drastically improve the speed of dev if I had a predetermined test wallet address so that I can:

  • Update the contract
  • Build the contract
  • Deploy using localTestNode
  • Connect to same deployer wallet on local node to test making changes to contract in dapp

Let me know if I’m wrong here or what the desired approach would be - I basically really just want to replace the dapp example with a localNode and deterministic wallet address.

Hope that makes sense, thx!

Also sidenote: We are developing in Svelte/Sveltekit, not Next, so the example is helpful, but we need to make our own setup.

@xpluscal The launchTestNode utility is geared towards testing only; it should never be used inside your app code.

Is that what you’re trying to do?

@xpluscal We could better assist you if you provided a public repo that mimics your setup and what you’re trying to achieve. Do you think you could do that?

Absolutely not.

My goal is to improve the local development UX for full stack.

@anderson heres the public repo with file in question:

All I want to achieve is to:

  • Pass a predefined wallet to the launchTestNode
  • Pass a predefined PORT so that the test node launches with a specific port.

Those two things would allow to reliable have my dapp be able to be locally developed against a localNode using the same wallet and endpoint without having to change those in my fuel wallet every time a dev starts the local node script again…

Does that make sense?

My goal is to improve the local development UX for full stack.

Thank you for the involvement!

The fuels cli is the utility one should use for local development. The launchTestNode utility should be used for tests exclusively (*.test.ts files).

Based on your requirements in your comment, it seems to me that everything can be achieved via the fuels cli and that you are essentially trying to recreate the fuels cli via launchTestNode. A bare-bones fuels.config.ts that satisfies your needs might be:

// fuels.config.ts
export default createConfig({
  workspace: './your-sway-programs-dir',
  output: './src/types',
});

You would then run pnpm fuels dev which would build your programs, generate types and deploy your contracts onto the local node that was spun up on localhost:4000. The node would then continue to run on that port and you can develop against with it in your app. You can define a lot of other fields in the createConfig function so I suggest you investigate it further.

I highly suggest you take a look at the files generated from pnpm create fuels@0.92.0, specifically fuels.config.ts and the pnpm fuels:dev command from package.json. The app has fuel wallet integration, local and testnet support, uses the same wallet and endpoint just as you need it, etc. You’d just need to swap out the next app for your svelte app.


On the topic of launchTestNode and its capabilitites:

Pass a predefined wallet to the launchTestNode

Currently you can’t do that. We could add support for that and a full example where something can’t be done (or would be hard to do) except by predefining a wallet would be great and would bump the priority of the issue. The example that you sent us doesn’t contain such an use case, though, because it’s essentially the advanced example, just wrapped in an IIFE.

Pass a predefined PORT so that the test node launches with a specific port.

You can do this via the nodeOptions.port property:

using launched = await launchTestNode({ nodeOptions: { port: '4567' } });

But this is not in the spirit of the utility because that node should be killed once the test exits. A fuel-core node shouldn’t be shared across tests. We created this utility for that specific reason of not sharing a fuel-core node across our tests because our test suite had test flakiness due to that coupling on the node level.

2 Likes

Thank you so much for your extensive reply.

I hadn’t seen the fuels:dev command in package json, very helpful.

Another helpful alternative for the predetermined wallet would be to stack the wallet with test eth on localnode. whats the current process for this?

Here’s the use case:

  • Run fuels:dev to start localnode + deploy contracts
  • Run your app locally
  • Now I need a wallet with local test eth to test my application or run through it.

What’s the current process for this then?

Another helpful alternative for the predetermined wallet would be to stack the wallet with test eth on localnode. whats the current process for this?

You can use the snapshotDir property when defining your fuels.config.ts file:

export default createConfig({
  // ...,
  snapshotDir: "path-to-the-directory",
});

You can copy/paste the contents of our config directory and change the stateConfig.json file to suit your needs. If you’re going to do this, I suggest you remove all the coins and messages from the stateConfig.json file and put in your own ones. You’re also going to have to specify the privateKey property in the fuels.config.ts file, which would match one of your coin owners, so that the wallet can be used to deploy your contracts.