@wuwei-labs/srsly
Version:
TypeScript SDK for SRSLY
98 lines • 4.9 kB
JavaScript
"use strict";
/**
* @purpose Simplified createContractThread instruction wrapper
*
* Thin convenience wrapper around Codama-generated createContractThread instruction.
* Creates a per-contract automation thread with fiber-based dispatch.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createContractThread = createContractThread;
const kit_1 = require("@solana/kit");
const instructions_1 = require("../generated/codama/instructions");
const config_1 = require("../utils/config");
const signer_1 = require("../utils/signer");
const instructions_2 = require("../utils/instructions");
const config_2 = require("../accounts/config");
const contract_1 = require("../accounts/contract");
const fleet_1 = require("../accounts/fleet");
const rental_1 = require("../accounts/rental");
const types_1 = require("../generated/codama/types");
const sage_1 = require("../pda/sage");
const srsly_1 = require("../pda/srsly");
const thread_1 = require("../pda/thread");
const srsly_2 = require("../pda/srsly");
const schedule_1 = require("../params/schedule");
const sol_1 = require("../params/sol");
const constants_1 = require("../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)
*/
async function createContractThread(params, config) {
const finalConfig = (0, config_1.mergeConfig)(config);
if (!params.owner) {
throw new Error('owner is required');
}
if (!params.contract) {
throw new Error('contract is required');
}
const ownerSigner = (0, signer_1.toTransactionSigner)(params.owner);
const ownerAddress = (0, signer_1.getSignerAddress)(params.owner);
// Get atlasMint and sage program from config
const configAccount = await (0, config_2.fetchConfig)(finalConfig.rpcUrl);
const atlasMint = configAccount.data.atlasMint;
const addresses = (0, config_1.getAddresses)(config);
const programAddress = (0, kit_1.address)(addresses.srsly);
// Fetch contract to get managed_token_account
const contractAccount = await (0, contract_1.fetchContract)(params.contract, finalConfig.rpcUrl);
const contractAddress = (0, kit_1.address)(params.contract);
// Derive thread and fiber PDAs
const rentalAuthority = await (0, srsly_2.deriveRentalAuthority)();
const contractThread = await (0, thread_1.deriveContractThread)(contractAddress, rentalAuthority);
const fiber0 = await (0, thread_1.deriveFiber)(contractThread, 0);
const closeRentalFiber = await (0, thread_1.deriveFiber)(contractThread, 1);
// Normalize schedule to cron string
const paymentsFreq = (0, schedule_1.normalizeSchedule)(params.paymentsFreq);
const kitInstruction = await (0, instructions_1.getCreateContractThreadInstructionAsync)({
payer: ownerSigner,
mint: atlasMint,
contract: contractAddress,
contractThread,
fiber0,
closeRentalFiber,
owner: ownerAddress,
contractTokenAccount: contractAccount.data.managedTokenAccount,
sageProgram: (0, kit_1.address)(addresses.sage),
lamports: constants_1.MINIMUM_THREAD_FUNDING +
(params.lamports ? (0, sol_1.convertSol)(params.lamports) : constants_1.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 (0, srsly_1.deriveActiveRental)(contractAddress);
const activeRental = await (0, rental_1.fetchRental)(activeRentalPda, finalConfig.rpcUrl);
if (activeRental.data.status === types_1.RentalStatus.Active) {
const fleetState = await (0, fleet_1.fetchFleet)(contractAccount.data.fleet, finalConfig.rpcUrl);
const gameAccounts = await (0, sage_1.deriveGameAccounts)(fleetState.subProfile.key, fleetState.faction, contractAccount.data.gameId);
const sageRemainingAccounts = [
{ address: gameAccounts.starbase, role: kit_1.AccountRole.READONLY },
{ address: gameAccounts.starbasePlayer, role: kit_1.AccountRole.READONLY },
];
kitInstruction.accounts.push(...sageRemainingAccounts);
}
}
catch {
// No active rental — remaining_accounts not needed
}
return (0, instructions_2.prepareInstructions)(kitInstruction, {
computeUnits: params.computeUnits,
PublicKey: finalConfig.PublicKey,
});
}
//# sourceMappingURL=createContractThread.js.map