UNPKG

@wuwei-labs/srsly

Version:
95 lines 4.64 kB
/** * @purpose Simplified createContractThread instruction wrapper * * Thin convenience wrapper around Codama-generated createContractThread instruction. * Creates a per-contract automation thread with fiber-based dispatch. */ import { AccountRole, address } from '@solana/kit'; import { getCreateContractThreadInstructionAsync } from '../generated/codama/instructions'; import { mergeConfig, getAddresses } from '../utils/config'; import { toTransactionSigner, getSignerAddress } from '../utils/signer'; import { prepareInstructions } from '../utils/instructions'; import { fetchConfig } from '../accounts/config'; import { fetchContract } from '../accounts/contract'; import { fetchFleet } from '../accounts/fleet'; import { fetchRental } from '../accounts/rental'; import { RentalStatus } from '../generated/codama/types'; import { deriveGameAccounts } from '../pda/sage'; import { deriveActiveRental } from '../pda/srsly'; import { deriveContractThread, deriveFiber } from '../pda/thread'; import { deriveRentalAuthority } from '../pda/srsly'; import { normalizeSchedule } from '../params/schedule'; import { convertSol } from '../params/sol'; import { MINIMUM_THREAD_FUNDING, DEFAULT_EXECUTION_BUDGET } from '../cost/constants'; /** * Set up the per-contract automation thread that processes payments and * lifecycle ticks. Thread starts paused; the rental_close and * rental_activate fibers spin up lazily on first use. * * @param params - Thread creation parameters * @param config - Optional SDK configuration overrides * @returns Kit instruction (or web3.js if PublicKey in config) */ export async function createContractThread(params, config) { const finalConfig = mergeConfig(config); if (!params.owner) { throw new Error('owner is required'); } if (!params.contract) { throw new Error('contract is required'); } const ownerSigner = toTransactionSigner(params.owner); const ownerAddress = getSignerAddress(params.owner); // Get atlasMint and sage program from config const configAccount = await fetchConfig(finalConfig.rpcUrl); const atlasMint = configAccount.data.atlasMint; const addresses = getAddresses(config); const programAddress = address(addresses.srsly); // Fetch contract to get managed_token_account const contractAccount = await fetchContract(params.contract, finalConfig.rpcUrl); const contractAddress = address(params.contract); // Derive thread and fiber PDAs const rentalAuthority = await deriveRentalAuthority(); const contractThread = await deriveContractThread(contractAddress, rentalAuthority); const fiber0 = await deriveFiber(contractThread, 0); const closeRentalFiber = await deriveFiber(contractThread, 1); // Normalize schedule to cron string const paymentsFreq = normalizeSchedule(params.paymentsFreq); const kitInstruction = await getCreateContractThreadInstructionAsync({ payer: ownerSigner, mint: atlasMint, contract: contractAddress, contractThread, fiber0, closeRentalFiber, owner: ownerAddress, contractTokenAccount: contractAccount.data.managedTokenAccount, sageProgram: address(addresses.sage), lamports: MINIMUM_THREAD_FUNDING + (params.lamports ? convertSol(params.lamports) : DEFAULT_EXECUTION_BUDGET), paymentsFreq, }, { programAddress }); // If active rental exists, append starbase + starbasePlayer as remaining_accounts // (Rust reads them from remaining_accounts when building fiber 1 close instruction) try { const activeRentalPda = await deriveActiveRental(contractAddress); const activeRental = await fetchRental(activeRentalPda, finalConfig.rpcUrl); if (activeRental.data.status === RentalStatus.Active) { const fleetState = await fetchFleet(contractAccount.data.fleet, finalConfig.rpcUrl); const gameAccounts = await deriveGameAccounts(fleetState.subProfile.key, fleetState.faction, contractAccount.data.gameId); const sageRemainingAccounts = [ { address: gameAccounts.starbase, role: AccountRole.READONLY }, { address: gameAccounts.starbasePlayer, role: AccountRole.READONLY }, ]; kitInstruction.accounts.push(...sageRemainingAccounts); } } catch { // No active rental — remaining_accounts not needed } return prepareInstructions(kitInstruction, { computeUnits: params.computeUnits, PublicKey: finalConfig.PublicKey, }); } //# sourceMappingURL=createContractThread.js.map