@wuwei-labs/srsly
Version:
TypeScript SDK for SRSLY
146 lines • 6.83 kB
JavaScript
"use strict";
/**
* @purpose Simplified createContract instruction wrapper
*
* Thin convenience wrapper around Codama-generated createContract instruction.
* Handles parameter conversion and optional web3.js compatibility.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createContract = createContract;
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 amount_1 = require("../params/amount");
const duration_1 = require("../params/duration");
const schedule_1 = require("../params/schedule");
const sol_1 = require("../params/sol");
const fleet_1 = require("../accounts/fleet");
const config_2 = require("../accounts/config");
const instructions_2 = require("../utils/instructions");
const srsly_1 = require("../pda/srsly");
const thread_1 = require("../pda/thread");
const token_1 = require("../pda/token");
/**
* List a Star Atlas fleet for rent. Sets the per-period rate, allowed
* duration window, fee, and (optionally) automation parameters.
*
* @param params - Contract creation parameters
* @param config - Optional SDK configuration overrides
* @returns Kit instruction (or web3.js if PublicKey in config)
*
* @example
* ```typescript
* // With global config - auto-fetch ownerProfile and gameId from fleet
* setSdkConfig({ network: 'atlasnet' });
* const ix = await createContract({
* owner: wallet,
* fleet: fleetAddress,
* rate: 100,
* durationMax: { days: 30 }
* });
* ```
*/
async function createContract(params, config) {
// Merge config
const finalConfig = (0, config_1.mergeConfig)(config);
// Validate required params
if (!params.owner) {
throw new Error('owner is required');
}
if (!params.fleet) {
throw new Error('fleet is required');
}
if (!params.rate) {
throw new Error('rate is required');
}
if (!params.durationMax) {
throw new Error('durationMax is required');
}
// Convert owner to transaction signer
const ownerSigner = (0, signer_1.toTransactionSigner)(params.owner);
// Fetch fleet data (source of truth for ownerProfile and gameId)
const fleetState = await (0, fleet_1.fetchFleet)(params.fleet, finalConfig.rpcUrl);
const ownerProfile = fleetState.ownerProfile;
const gameId = fleetState.gameId;
// Convert parameters
const rateStardust = (0, amount_1.convertAmount)(params.rate);
// Validate minimum rate (1 ATLAS = 100_000_000 stardust)
const MIN_RATE_STARDUST = 100000000n;
if (rateStardust < MIN_RATE_STARDUST) {
throw new Error(`Rate too low. Minimum rate is 1 ATLAS (100,000,000 stardust). ` +
`Got: ${rateStardust} stardust (${(0, amount_1.stardustToAtlas)(rateStardust)} ATLAS)`);
}
const durationMinSeconds = params.durationMin ? (0, duration_1.convertDuration)(params.durationMin) : 3600; // Default 1 hour
const durationMaxSeconds = (0, duration_1.convertDuration)(params.durationMax);
// Validate duration logic
if (durationMaxSeconds < durationMinSeconds) {
throw new Error(`durationMax (${durationMaxSeconds}s) must be >= durationMin (${durationMinSeconds}s)`);
}
// Get atlasMint from on-chain config
const configAccount = await (0, config_2.fetchConfig)(finalConfig.rpcUrl);
const atlasMint = configAccount.data.atlasMint;
const addresses = (0, config_1.getAddresses)(config);
const sageProgram = (0, kit_1.address)(addresses.sage);
const programAddress = (0, kit_1.address)(addresses.srsly);
// Convert cancelDelayMin duration to seconds. Default mirrors
// `durationMin` so a borrower can never cancel out of a rental
// earlier than the contract's own minimum lease window — the owner
// is guaranteed at least one full minimum-duration of revenue.
const cancelDelayMinSeconds = params.cancelDelayMin !== undefined
? BigInt((0, duration_1.convertDuration)(params.cancelDelayMin))
: BigInt(durationMinSeconds);
// Call Codama-generated instruction
const kitInstruction = await (0, instructions_1.getCreateContractInstructionAsync)({
owner: ownerSigner,
fleet: (0, kit_1.address)(params.fleet),
ownerProfile: (0, kit_1.address)(ownerProfile),
gameId: (0, kit_1.address)(gameId),
mint: atlasMint,
sageProgram,
rate: rateStardust,
durationMin: BigInt(durationMinSeconds),
durationMax: BigInt(durationMaxSeconds),
ownerKeyIndex: params.ownerKeyIndex ?? 0,
cancelDelayMin: cancelDelayMinSeconds,
reservationsDisabled: params.reservationsDisabled ?? true,
contestedThreshold: params.contestedThreshold ?? 1,
}, { programAddress });
// Default: bundle thread creation for automation
if (params.automated !== false) {
const paymentsFreq = (0, schedule_1.normalizeSchedule)(params.paymentsFreq ?? '@daily');
// Derive PDAs locally (contract doesn't exist on-chain yet)
const contractAddress = await (0, srsly_1.deriveContract)(params.fleet);
const contractTokenAccount = await (0, token_1.deriveAssociatedTokenAccount)(contractAddress, atlasMint);
const rentalAuthority = await (0, srsly_1.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);
const ownerAddress = (0, signer_1.getSignerAddress)(params.owner);
const MINIMUM_THREAD_FUNDING = 40000000n;
const DEFAULT_EXECUTION_BUDGET = 2190000n; // 1 year daily @ 0.000006 SOL/tick
const threadIx = await (0, instructions_1.getCreateContractThreadInstructionAsync)({
payer: ownerSigner,
mint: atlasMint,
contract: contractAddress,
contractThread,
fiber0,
closeRentalFiber,
owner: ownerAddress,
contractTokenAccount,
sageProgram,
lamports: MINIMUM_THREAD_FUNDING +
(params.threadLamports ? (0, sol_1.convertSol)(params.threadLamports) : DEFAULT_EXECUTION_BUDGET),
paymentsFreq,
}, { programAddress });
return (0, instructions_2.prepareInstructions)([kitInstruction, threadIx], {
computeUnits: params.computeUnits,
PublicKey: finalConfig.PublicKey,
});
}
return (0, instructions_2.prepareInstructions)(kitInstruction, {
computeUnits: params.computeUnits,
PublicKey: finalConfig.PublicKey,
});
}
//# sourceMappingURL=createContract.js.map