1.5.7 • Published 3 months ago

factory-sol-client v1.5.7

Weekly downloads
-
License
-
Repository
-
Last release
3 months ago

github: https://git.kryptonhub.com/factory-game/factory-sol-client.git branch: client.0.1.2

Changelog

new instruction to deinstall equipment from board's warehouse

    deinstallEquipmentFromBoardEscrowWithWarehouse

old one is deprecated and will be removed in next version

############################# Client 0.1.2. Add board's warhouse ############################################ The boards of version 0.1.1 will work fine. To use board's warehouse you have to: 1. For each board account, create a corresponding warehouse account using the addBoardWarehouse instruction. To generate the public key for this warehouse account, utilize the following JavaScript function:

let boardWarehousePk = await utils.get_warehouse_address(
            SEEDS.WAREHOUSE_SEED,
            boardPublicKey,
            utils.PROGRAM_ID
        );
  1. Due to the removal of the belts strategy, you can now connect any equipment placed on the board directly to the board’s warehouse. This ensures a seamless flow and efficient management of resources. Here’s how to do it:
//Connect equipment to the board's warehouse
await utils.program.methods
            .setRecipeWithWarehouse(
                node_idx,
                equipment_idx,
                tree_name,
                recipe_idx,
                seed0,
                seed1,
                seed2
            )
            .accounts({
                adminTokenAccount: adminTokenAccount,
                board: boardPk,
                tree: treePk,
                boardWarehouse: warehousePk,
                equipmentLedger: equipmentLedger,
                recipeLedger: recipeLedger,
                owner: user.publicKey,
                systemProgram: anchor.web3.SystemProgram.programId,
            })
            .signers([user])
            .rpc();
  1. To disconnect equipment, use the clearRecipeWithWarehouse instruction. The program will reject any transactions that would result in a resource deficit (negative flow of resource):
await utils.program.methods
            .clearRecipeWithWarehouse(
                node_idx,
                equipment_idx,
                tree_name,
                recipe_idx,
                seed0,
                seed1,
                seed2
            )
            .accounts({
                adminTokenAccount: adminTokenAccount,
                board: boardPk,
                tree: treePk,
                boardWarehouse: warehousePk,
                equipmentLedger: equipmentLedger,
                recipeLedger: recipeLedger,
                owner: user.publicKey,
                systemProgram: anchor.web3.SystemProgram.programId,
            })
  1. Resources stored in the board's warehouse can be collected using the collectFromBoardWarehouse method.
await utils.program.methods
        .collectFromBoardWarehouse(
            amount,
            resource_idx,
            seed0,
            seed1,
            seed2
        )
        .accounts({
            adminTokenAccount: admin_token_account,
            board: boardPk,
            boardWarehouse: warehousePk,
            resourceLedger: resource_ledger,
            minter: minter,
            mint: resource.mint[CLUSTER],
            targetAccount: resource_deposit_account,
            owner: user.publicKey,
            tokenProgram: TOKEN_PROGRAM_ID,
        })

################################# Client 0.1.1. Testing boards ############################################### //30, 30, 30, mint: EX8F8gjzyDEGMwpNHkJ66hT2ejBKxA2tGxd7DWnfLZWY //30, 30, 31, mint: 3bkHwqaXQc2SJK59ZQFXafjuhGiQuFf37uYN63VwEUTi //30, 30, 32, mint: ArJtSGTmybGdEe4Luff9cvLsX1bYP8S7nmCjbbk9AreA //30, 30, 33, mint: xFdZWHgLbWc4TfyAkX46d9mhboHWnf3emXpQuHyycAr //30, 30, 34, mint: 2Dkx7drMYoZFs7P3bknDgsvvaSXaCvE794SfSz8BsWam Changelog for Solana Factorio ################################## Version 0.1.1 ############################################################# Major Changes Aimed at Enhancing Production Nodes:

Expanded Solana Accounts Integration:

  1. Separate account for field's data Introduced separate Solana accounts to store field data. This enables a more robust and organized system for managing an expanded number of production nodes.

  2. Separate accounts for tree's data For every production tree, a dedicated Solana account has been introduced. This architectural change allows for the utilization of more production nodes per board, preventing memory errors and enhancing overall performance.

  3. Program ID Update Program ID Update: (Temporary?) New program id: AsxJsrHN1ehipnbRjCMC2Q5Dy1QNRp9KgZVvgb6iAcK4

  4. Backward Incompatibility: The 0.1.1 update renders all previous boards incompatible with the new version. This is a significant breaking change, as users with older boards will be unable to use them in the new version without some form of migration or upgrade process.

Changes from version 0.1.0 to 0.1.1:

  1. Field Address Deriving from seeds: In version 0.1.1, after getting the board address, you also retrieve the field address using the function utils.get_field_address. This is not present in the 0.1.0 version.

    let fieldPk = await utils.get_field_address(
         SEEDS.FIELD_SEED,
         boardPublicKey,
         utils.PROGRAM_ID);
  2. Tree Name Extraction: In version 0.1.1, you extract the tree name from the board's treeNames property using the given tree_idx.

    let tree_name = board.treeNames[tree_idx];
  3. Tree Address Deriving from seeds and tree name: Version 0.1.1 includes fetching the tree address using the function utils.get_tree_address. This leverages the extracted tree name along with the board address and program ID.

    let treePk = await utils.get_tree_address(
         SEEDS.TREE_SEED, 
         tree_name,
         boardPublicKey,
         utils.PROGRAM_ID
     );

################################## Version 0.1.0 #############################################################

fact_sol_client

A TypeScript library to interact with the Solana on-chain program for the Factorio game.

For testing purposes, a user wallet was created and funded with SOL, and SPL tokens were used as equipment in the Factorio program. User wallets are stored in the ./keypairs folder.

A board account was also created with seeds 'genesis-0-0-4', 2, 2, 2. All seeds used in the program are stored in the ./utils/seeds.ts file.

When a board account is created by an admin user, a new mint is created and associated with the board account. One token of this mint is minted and transferred to the user wallet.

All transactions that modify the board account are signed by the user wallet. The associated token account is checked to ensure it is owned by the user wallet and has exactly one token.

How to interact with program

Ledgers

The Factorio program has three ledgers: EquipmentLedger, RecipeLedger, and ResourceLedger. All game-related information is stored in these ledgers. Public keys of these ledgers are derived from the seeds. The seeds are stored in the ./utils/seeds.ts file.

export const RESOURCE_SEED = "resource_3";
export const RECIPE_SEED = "recipe_4";
export const EQUIPMENT_SEED = "equipment_6";

setName transaction example

First, derive the admin's associated token account address from the user wallet address and the board mint address using the getAssociatedTokenAddress function from the @solana/spl-token package. Next, derive the board account address from the seeds using the get_board_address function from the ./utils/utils.ts file.

import { getAssociatedTokenAddress } from "@solana/spl-token";
import { setName } from "../client/instructions";
import * as utils from "../utils/utils";
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";

export async function set_board_name(
    seed1: number,
    seed2: number,
    seed3: number,
    board_domen_seed: string,
    board_mint: PublicKey,
    user: Keypair
): Promise<Transaction> {
    const tx = new Transaction()
    const ix = setName({
        seed1: seed1,
        seed2: seed2,
        seed3: seed3,
        newName: "NewUserName"
    }, 
    {
        adminTokenAccount: await getAssociatedTokenAddress(
            board_mint,
            user.publicKey
        ),
        board: await utils.get_board_address(
            board_domen_seed,
            seed1,
            seed2,
            seed3,
            utils.PROGRAM_ID),
        owner: user.publicKey,
    })
    tx.add(ix);
    return tx;
}

addTree transaction example

The board has a square field to place equipment. Each cell of the field is defined by (x, y) coordinates. Additionally, all equipment must be added to a production tree. To start producing something, you need to add at least one tree to the board. Therefore, to place equipment on the board, you need to specify the tree ID and the coordinates of the cell where you want to place the equipment.

First, you need to derive the admin's associated token account address from the user wallet address and the board mint address. To do this, use the getAssociatedTokenAddress function from the @solana/spl-token package.

Next, derive the board account address from the seeds using the get_board_address function from the ./utils/utils.ts file.

import { addTree } from "../client/instructions";
import { getAssociatedTokenAddress } from "@solana/spl-token";
import * as utils from "../utils/utils";
import { Keypair, PublicKey, Transaction, SystemProgram } from "@solana/web3.js";

export async function add_tree(
    tree_name: string,
    seed1: number,
    seed2: number,
    seed3: number,
    board_domen_seed: string,
    board_mint: PublicKey,
    user: Keypair) : Promise<Transaction> {
    const tx = new Transaction()
    const ix = addTree({
            seed1: seed1,
            seed2: seed2,
            seed3: seed3,
            name: tree_name
        },
        {
            adminTokenAccount: await getAssociatedTokenAddress(
                board_mint,
                user.publicKey),
            board: await utils.get_board_address(
                board_domen_seed,
                seed1,
                seed2,
                seed3,
                utils.PROGRAM_ID),
            systemProgram: SystemProgram.programId,
            owner: user.publicKey,
        })
        tx.add(ix);
        return tx
    }

initEscrow

All equipment types are represented by an SPL-token mint. To place equipment on the board, you must have at least one token of this mint. When you install equipment on the board, one token of this mint is transferred from your wallet to an escrow account. Therefore, to install equipment, you need to initialize an escrow account for this equipment mint, and then transfer the token to this escrow account. You have to store the PublicKey of equipmentDepositAccount off-chain to be able to transfer tokens to it later.

export interface InitBoardEquipmentEscrowAccounts {
  equipmentMint: PublicKey // mint of equipment
  board: PublicKey //board account derived from seeds
  adminTokenAccount: PublicKey //admin token account associated with board mint and user wallet, must have balance>0
  equipmentDepositAccount: PublicKey //you must generate this account by anchor.web3.Keypair.generate();
  boardEscrow: PublicKey //you must derive this account: let [board_escrow, _] = await PublicKey.findProgramAddress([encode("board_escrow"), board_.toBuffer(), equipment_mint.toBuffer()], utils.PROGRAM_ID);
  owner: PublicKey //user wallet
  tokenProgram: PublicKey //spl-token program id
  systemProgram: PublicKey //system program id
  rent: PublicKey //rent program id
}

installEquipment

To install equipment on the board, you need to transfer a token from the user wallet to the escrow account. All game-related information about equipment is stored in the EquipmentLedger. Therefore, you need to provide the index for this equipment in the EquipmentLedger. Additionally, you need to provide the tree ID, coordinates of the cell where you want to place the equipment, and the rotation of the equipment.

export interface InstallEquipmentWithBoardEscrowAccounts {
  equipmentMint: PublicKey //mint of equipment
  board: PublicKey //board account derived from seeds
  adminTokenAccount: PublicKey //admin token account associated with board mint and user wallet, must have balance>0
  equipmentSourceAccount: PublicKey //user token account associated with equipment mint and user wallet, must have balance>0
  equipmentDepositAccount: PublicKey //account to which the token is transferred from the user wallet, was generated in initBoardEquipmentEscrow
  equipmentLedger: PublicKey //equipment ledger account
  boardEscrow: PublicKey //board escrow account derived from seeds: [encode("board_escrow"), board_.toBuffer(), equipment_mint.toBuffer()]
  owner: PublicKey //user wallet
  tokenProgram: PublicKey //spl-token program id
  systemProgram: PublicKey //system program id
}

setRecipe

To produce something, you need to set a recipe for the installed equipment. The recipe is a list of input ingredients and only one output ingredient. The recipe is stored in the RecipeLedger. Therefore, you need to provide the index for this recipe in the RecipeLedger. Additionally, you need to provide the tree ID, and index of node, where you want to place the recipe and index of equipment in EquipmentLedger. According to game mechanics production starts immediately after setting the recipe, if the equipment has enough input ingredients.

export interface SetRecipeArgs {
  nodeIdx: number //index of node in tree
  equipmentIdx: number //index of equipment in EquipmentLedger
  treeIdx: number //index of tree on board
  recipeIdx: number //index of recipe in RecipeLedger
  seed1: number //seed1 used to derive board account
  seed2: number //seed2 used to derive board account
  seed3: number //seed3 used to derive board account
}

export interface SetRecipeAccounts {
  board: PublicKey //board account derived from seeds
  adminTokenAccount: PublicKey //admin token account associated with board mint and user wallet, must have balance>0
  recipeLedger: PublicKey //recipe ledger account
  equipmentLedger: PublicKey //equipment ledger account
  owner: PublicKey //user wallet
  systemProgram: PublicKey //system program id
}

Belts

Belts used to connect nodes in the tree. Belts placed on board only between nodes, each belt segment occupies one cell. Each belt's segment have orientation (horisontal or vertical). Two segments can intersect only if they have a different orientation.

connectNodesWithBelt

To connect two nodes with a belts, you need to provide the tree ID, and indexes of parent and child nodes. The connection will be established only if the parent node has a recipe with the input ingredient, which is the output ingredient of the child node. Also you need to provide the seeds for the board account and the three arrays two of them define belt's points coordinates and one of them defines belt's direction (horisontal or vertical). Belt's segments must be interconnected between each other.

export interface ConnectNodesWithBeltArgs {
  childNodeIdx: number //index of child node, the output ingredient of which will be the input ingredient of the parent node
  parentNodeIdx: number //index of parent node, the input ingredient of which will be the output ingredient of the child node
  treeIdx: number //index of tree on board, where nodes are located
  seed1: number //seed1 used to derive board account
  seed2: number //seed2 used to derive board account
  seed3: number //seed3 used to derive board account
  xs: Uint8Array //array of x coordinates of belt's points
  ys: Uint8Array //array of y coordinates of belt's points
  horisontalFlags: Uint8Array //array of flags, which define belt's direction (horisontal or vertical)
}

export interface ConnectNodesWithBeltAccounts {
  board: PublicKey //board account derived from seeds
  adminTokenAccount: PublicKey //admin token account associated with board mint and user wallet, must have balance>0
  recipeLedger: PublicKey //recipe ledger account to check if parent node has a recipe with the input ingredient, which is the output ingredient of the child node
  owner: PublicKey //user wallet
}

collect

User can collect result of production only from nodes in witch warehouse is installed. To collect result of production in form of spl-tokens, user need to provide the tree ID, and index of node,

export interface CollectArgs {
  nodeIdx: number //index of node in tree
  treeIdx: number //index of tree on board
  amount: number //amount of tokens to collect
  resourseIdx: number //index of resource in ResourceLedger
  recipeIdx: number //index of recipe in RecipeLedger
  seed1: number //seed1 used to derive board account
  seed2: number //seed2 used to derive board account
  seed3: number //seed3 used to derive board account
}

export interface CollectAccounts {
  board: PublicKey //board account derived from seeds
  adminTokenAccount: PublicKey //admin token account associated with board mint and user wallet, must have balance>0
  resourceLedger: PublicKey //resource ledger account
  mint: PublicKey //mint of spl-token that associated with resource
  targetAccount: PublicKey //user token account associated with resource mint, tokens will be collected to this account
  recipeLedger: PublicKey //recipe ledger account
  minter: PublicKey //minter account derived from seeds: [encode("minter")]
  owner: PublicKey //user wallet
  tokenProgram: PublicKey //spl-token program id
}
1.5.4

3 months ago

1.5.3

3 months ago

1.5.7

3 months ago

1.5.6

3 months ago

1.4.6

6 months ago

1.5.2

6 months ago

1.5.1

6 months ago

1.4.5

8 months ago

1.4.4

8 months ago

1.4.3

9 months ago

1.4.2

9 months ago

1.4.1

9 months ago

1.4.0

9 months ago

1.3.0

9 months ago

1.2.3

9 months ago

1.2.2

9 months ago

1.2.1

9 months ago

1.2.0

9 months ago