Skip to content

Commit

Permalink
Created emulator service
Browse files Browse the repository at this point in the history
Close #287
  • Loading branch information
tombeckenham committed Dec 24, 2024
1 parent a1a3940 commit 2150d3b
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 49 deletions.
6 changes: 6 additions & 0 deletions src/background/controller/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3410,6 +3410,9 @@ export class WalletController extends BaseController {
case 'mainnet':
baseURL = 'https://evm.flowscan.io';
break;
case 'emulator':
// TODO: add emulator for EVM flowscan url
break;
}
} else {
// Set baseURL based on the network
Expand Down Expand Up @@ -3445,6 +3448,9 @@ export class WalletController extends BaseController {
case 'crescendo':
baseURL = 'https://f.dnz.dev';
break;
case 'emulator':
baseURL = 'http://localhost:8888';
break;
}
return baseURL;
};
Expand Down
208 changes: 208 additions & 0 deletions src/background/service/emulator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import { type NFTModel, type NFTData } from './networkModel';

const EMULATOR_HOST = 'http://localhost:8888';

class EmulatorService {
// Transaction related
async getTransfers(address: string, cursor: string, limit: number) {
try {
const response = await fetch(
`${EMULATOR_HOST}/v1/accounts/${address}/transactions?limit=${limit}`
);
const data = await response.json();
return {
data: {
transactions: data.transactions || [],
total: data.transactions?.length || 0,
},
};
} catch (error) {
console.error('Error getting transfers:', error);
return {
data: {
transactions: [],
total: 0,
},
};
}
}

// NFT related
async nftCatalogList(
address: string,
limit: number,
offset: number,
network: string
): Promise<NFTData> {
try {
// Get all NFT collections for the account
const response = await fetch(`${EMULATOR_HOST}/v1/accounts/${address}/storage`);
const data = await response.json();

// Filter for NFT collections in storage
const nfts = Object.entries(data)
.filter(([key]) => key.includes('NFT'))
.map(([key, value]) => ({
id: key,
collectionName: key,
name: key,
description: '',
thumbnail: '',
// Add other required NFT fields
}));

return {
nfts: nfts.slice(offset, offset + limit),
nftCount: nfts.length,
};
} catch (error) {
console.error('Error getting NFT catalog:', error);
return {
nfts: [],
nftCount: 0,
};
}
}

async nftCatalogCollections(address: string, network: string) {
try {
// Get all collections from the account's storage
const response = await fetch(`${EMULATOR_HOST}/v1/accounts/${address}/storage`);
const data = await response.json();

// Filter for NFT collections
return Object.entries(data)
.filter(([key]) => key.includes('NFT'))
.map(([key]) => ({
name: key,
address: address,
count: 1, // Default count, could be updated with actual count if available
}));
} catch (error) {
console.error('Error getting NFT collections:', error);
return [];
}
}

// Scripts related
async cadenceScriptsV2() {
// Return default scripts for emulator
return {
scripts: {
emulator: {
basic: {
revokeKey: `
transaction(keyIndex: Int) {
prepare(signer: AuthAccount) {
signer.keys.revoke(keyIndex: keyIndex)
}
}
`,
},
storage: {
getStorageInfo: `
pub fun main(address: Address): {String: UFix64} {
let account = getAccount(address)
let used = account.storageUsed
let capacity = account.storageCapacity
return {
"used": used,
"capacity": capacity,
"available": capacity - used
}
}
`,
},
},
},
version: '1.0',
};
}

// Storage related
async getStorageInfo(address: string, network: string) {
try {
const response = await fetch(`${EMULATOR_HOST}/v1/accounts/${address}/storage`);
const data = await response.json();
return {
used: data.storageUsed || '0',
capacity: data.storageCapacity || '0',
available: (Number(data.storageCapacity || 0) - Number(data.storageUsed || 0)).toString(),
};
} catch (error) {
console.error('Error getting storage info:', error);
return {
used: '0',
capacity: '0',
available: '0',
};
}
}

// Account related
async getAccount(address: string, network: string) {
try {
const response = await fetch(`${EMULATOR_HOST}/v1/accounts/${address}`);
const data = await response.json();
return {
address: data.address || address,
balance: data.balance || '0',
code: data.code || '',
contracts: data.contracts || {},
keys: data.keys || [],
};
} catch (error) {
console.error('Error getting account:', error);
return {
address: address,
balance: '0',
code: '',
contracts: {},
keys: [],
};
}
}

// Block related
async getLatestBlock(network: string) {
try {
const response = await fetch(`${EMULATOR_HOST}/v1/blocks?height=sealed`);
const data = await response.json();
const block = data.length > 0 ? data[0] : null;
return {
height: block?.height || '0',
id: block?.id || '',
parentId: block?.parent_id || '',
timestamp: block?.timestamp || '',
};
} catch (error) {
console.error('Error getting latest block:', error);
return {
height: '0',
id: '',
parentId: '',
timestamp: '',
};
}
}

// Events related
async getEvents(eventType: string, startHeight: number, endHeight: number, network: string) {
try {
const response = await fetch(
`${EMULATOR_HOST}/v1/events?type=${eventType}&start_height=${startHeight}&end_height=${endHeight}`
);
const data = await response.json();
return {
events: data.events || [],
};
} catch (error) {
console.error('Error getting events:', error);
return {
events: [],
};
}
}
}

export const emulatorService = new EmulatorService();
53 changes: 4 additions & 49 deletions src/background/service/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { getFirbaseConfig, getFirbaseFunctionUrl } from 'background/utils/fireba
import fetchConfig from 'background/utils/remoteConfig';
import { INITIAL_OPENAPI_URL, WEB_NEXT_URL } from 'consts';

import { fclMainnetConfig, fclTestnetConfig } from '../fclConfig';
import { fclEmulatorConfig, fclMainnetConfig, fclTestnetConfig } from '../fclConfig';

import {
type AccountKey,
Expand Down Expand Up @@ -120,6 +120,9 @@ const fclSetup = async () => {
case 'testnet':
await fclTestnetConfig();
break;
case 'emulator':
await fclEmulatorConfig();
break;
}
};

Expand Down Expand Up @@ -691,54 +694,6 @@ class OpenApiService {
return data;
};

login = async (
public_key: string,
signature: string,
replaceUser = true
): Promise<SignInResponse> => {
const config = this.store.config.login;
// const result = await this.request[config.method](config.path, {
// public_key,
// signature,
// });
const result = await this.sendRequest(
config.method,
config.path,
{},
{ public_key, signature }
);
if (!result.data) {
throw new Error('NoUserFound');
}
if (replaceUser) {
await this._signWithCustom(result.data.custom_token);
await storage.set('currentId', result.data.id);
}
return result;
};

loginV2 = async (
public_key: string,
signature: string,
replaceUser = true
): Promise<SignInResponse> => {
const config = this.store.config.loginv2;
const result = await this.sendRequest(
config.method,
config.path,
{},
{ public_key, signature }
);
if (!result.data) {
throw new Error('NoUserFound');
}
if (replaceUser) {
await this._signWithCustom(result.data.custom_token);
await storage.set('currentId', result.data.id);
}
return result;
};

loginV3 = async (
account_key: any,
device_info: any,
Expand Down

0 comments on commit 2150d3b

Please sign in to comment.