@@ -44,6 +44,7 @@ export interface RamInfo {
4444 hasEnoughRam : boolean
4545 hasEnoughTokens : boolean
4646 ramToBuy : number
47+ hasSystemContract : boolean // Whether the chain has full system contracts (RAM market)
4748}
4849
4950export interface AccountResources {
@@ -99,48 +100,56 @@ export async function getCoreSymbol(client: APIClient): Promise<string> {
99100
100101/**
101102 * Get RAM price from the rammarket table using Bancor algorithm
103+ * Falls back to default values for local chains without system contracts
102104 */
103105export async function getRamPrice (
104106 client : APIClient
105- ) : Promise < { pricePerByte : number ; symbol : string } > {
106- const rammarket = await client . v1 . chain . get_table_rows ( {
107- code : 'eosio' ,
108- scope : 'eosio' ,
109- table : 'rammarket' ,
110- limit : 1 ,
111- } )
107+ ) : Promise < { pricePerByte : number ; symbol : string ; hasSystemContract : boolean } > {
108+ try {
109+ const rammarket = await client . v1 . chain . get_table_rows ( {
110+ code : 'eosio' ,
111+ scope : 'eosio' ,
112+ table : 'rammarket' ,
113+ limit : 1 ,
114+ } )
112115
113- if ( rammarket . rows . length === 0 ) {
114- throw new Error ( 'Could not fetch RAM market data' )
115- }
116+ if ( rammarket . rows . length === 0 ) {
117+ // No RAM market data, this is a simple local chain
118+ return { pricePerByte : 0.00000001 , symbol : 'SYS' , hasSystemContract : false }
119+ }
116120
117- const state = rammarket . rows [ 0 ]
118-
119- // Parse base (RAM) and quote (tokens) from the market
120- // Base is RAM bytes, Quote is the token (e.g., EOS)
121- let baseBalance : number
122- let quoteBalance : number
123- let symbol = 'EOS'
124-
125- // Handle different response formats
126- if ( state . base ?. balance ) {
127- // Format: { balance: "123456789 RAM", weight: "0.50000000000000000" }
128- const baseStr = state . base . balance
129- baseBalance = parseFloat ( baseStr . split ( ' ' ) [ 0 ] )
130- const quoteStr = state . quote . balance
131- const quoteParts = quoteStr . split ( ' ' )
132- quoteBalance = parseFloat ( quoteParts [ 0 ] )
133- symbol = quoteParts [ 1 ] || 'EOS'
134- } else {
135- // Simpler format
136- baseBalance = parseFloat ( state . base )
137- quoteBalance = parseFloat ( state . quote )
138- }
121+ const state = rammarket . rows [ 0 ]
122+
123+ // Parse base (RAM) and quote (tokens) from the market
124+ // Base is RAM bytes, Quote is the token (e.g., EOS)
125+ let baseBalance : number
126+ let quoteBalance : number
127+ let symbol = 'EOS'
128+
129+ // Handle different response formats
130+ if ( state . base ?. balance ) {
131+ // Format: { balance: "123456789 RAM", weight: "0.50000000000000000" }
132+ const baseStr = state . base . balance
133+ baseBalance = parseFloat ( baseStr . split ( ' ' ) [ 0 ] )
134+ const quoteStr = state . quote . balance
135+ const quoteParts = quoteStr . split ( ' ' )
136+ quoteBalance = parseFloat ( quoteParts [ 0 ] )
137+ symbol = quoteParts [ 1 ] || 'EOS'
138+ } else {
139+ // Simpler format
140+ baseBalance = parseFloat ( state . base )
141+ quoteBalance = parseFloat ( state . quote )
142+ }
139143
140- // Bancor formula: price = quote_balance / base_balance
141- const pricePerByte = quoteBalance / baseBalance
144+ // Bancor formula: price = quote_balance / base_balance
145+ const pricePerByte = quoteBalance / baseBalance
142146
143- return { pricePerByte, symbol}
147+ return { pricePerByte, symbol, hasSystemContract : true }
148+ } catch {
149+ // RAM market might not exist on local chains, use default values
150+ // This allows deployment to proceed on simple local chains
151+ return { pricePerByte : 0.00000001 , symbol : 'SYS' , hasSystemContract : false }
152+ }
144153}
145154
146155/**
@@ -163,7 +172,8 @@ export async function getAccountResources(
163172 const balances = await client . v1 . chain . get_currency_balance ( 'eosio.token' , accountName )
164173 const matchingBalance = balances . find ( ( b ) => String ( b ) . includes ( symbol ) )
165174 coreBalance = matchingBalance || Asset . from ( `0.0000 ${ symbol } ` )
166- } catch ( e ) {
175+ } catch {
176+ // eosio.token might not exist on local chains, default to zero balance
167177 coreBalance = Asset . from ( `0.0000 ${ symbol } ` )
168178 }
169179
@@ -173,8 +183,8 @@ export async function getAccountResources(
173183 ramAvailable : ramQuota - ramUsage ,
174184 coreBalance,
175185 }
176- } catch ( error ) {
177- // Account might not exist yet
186+ } catch {
187+ // Account might not exist yet or other API errors
178188 return {
179189 ramQuota : 0 ,
180190 ramUsage : 0 ,
@@ -205,13 +215,14 @@ export async function analyzeRamRequirements(
205215 abiSize : number
206216) : Promise < RamInfo > {
207217 const ramBytesNeeded = calculateRamNeeded ( wasmSize , abiSize )
208- const { pricePerByte, symbol} = await getRamPrice ( client )
218+ const { pricePerByte, symbol, hasSystemContract } = await getRamPrice ( client )
209219 const resources = await getAccountResources ( client , accountName , symbol )
210220
211221 const ramToBuy = Math . max ( 0 , ramBytesNeeded - resources . ramAvailable )
212222 const costInTokens = calculateRamCost ( ramToBuy , pricePerByte , symbol )
213223
214- const hasEnoughRam = resources . ramAvailable >= ramBytesNeeded
224+ // On chains without system contracts, RAM is essentially free/unlimited
225+ const hasEnoughRam = ! hasSystemContract || resources . ramAvailable >= ramBytesNeeded
215226 const hasEnoughTokens = hasEnoughRam || resources . coreBalance . value >= costInTokens . value
216227
217228 return {
@@ -224,6 +235,7 @@ export async function analyzeRamRequirements(
224235 hasEnoughRam,
225236 hasEnoughTokens,
226237 ramToBuy,
238+ hasSystemContract,
227239 }
228240}
229241
@@ -480,6 +492,13 @@ export function displayRamAnalysis(ramInfo: RamInfo, accountName: string): void
480492 console . log ( `Account: ${ accountName } ` )
481493 console . log ( `RAM needed for deployment: ${ formatBytes ( ramInfo . ramBytesNeeded ) } ` )
482494 console . log ( `Current RAM available: ${ formatBytes ( ramInfo . currentRamAvailable ) } ` )
495+
496+ if ( ! ramInfo . hasSystemContract ) {
497+ console . log ( '─' . repeat ( 50 ) )
498+ console . log ( 'ℹ️ Local chain without system contracts - RAM management not required' )
499+ return
500+ }
501+
483502 console . log ( `RAM to purchase: ${ formatBytes ( ramInfo . ramToBuy ) } ` )
484503 console . log ( `Estimated cost: ${ ramInfo . costInTokens } ` )
485504 console . log ( `Current balance: ${ ramInfo . tokenBalance } ` )
0 commit comments