Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 38 additions & 18 deletions apps/app/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,45 @@
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
});

const config = [
// Extend Next.js config using compat
...compat.extends('next/core-web-vitals', 'next/typescript'),
import nextPlugin from '@next/eslint-plugin-next';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import tsParser from '@typescript-eslint/parser';
import tsPlugin from '@typescript-eslint/eslint-plugin';
import globals from 'globals';

export default [
js.configs.recommended,
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
parser: tsParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: { jsx: true },
},
globals: {
...globals.browser,
...globals.node,
React: 'readonly',
},
},
plugins: {
'@next/next': nextPlugin,
react: reactPlugin,
'react-hooks': reactHooksPlugin,
'@typescript-eslint': tsPlugin,
},
rules: {
// Next.js rules
...nextPlugin.configs.recommended.rules,
...nextPlugin.configs['core-web-vitals'].rules,

// React rules
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',

// TypeScript specific rules
'@typescript-eslint/no-unused-vars': [
'error',
Expand All @@ -27,6 +49,7 @@ const config = [
},
],
'@typescript-eslint/no-explicit-any': 'warn',
'no-unused-vars': 'off', // Use TypeScript version instead

// General JavaScript rules
'prefer-const': 'error',
Expand All @@ -41,10 +64,7 @@ const config = [
},
},
},

{
ignores: ['node_modules/', '.next/', 'out/', 'build/', 'dist/'],
},
];

export default config;
2 changes: 1 addition & 1 deletion apps/app/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
import './.next/types/routes.d.ts';

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
18 changes: 11 additions & 7 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "next dev --turbopack",
"build": "next build --turbopack",
"start": "next start",
"lint": "next lint",
"lint": "eslint src",
"type-check": "tsc --noEmit"
},
"dependencies": {
Expand All @@ -29,12 +29,12 @@
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@solana-program/system": "^0.7.0",
"@solana-program/token-2022": "^0.5.0",
"@solana/accounts": "^5.0.0",
"@solana/connector": "0.1.4",
"@solana/react": "^5.0.0",
"@solana/kit": "^5.0.0",
"@solana-program/system": "^0.7.0",
"@solana-program/token-2022": "^0.5.0",
"@solana/react": "^5.0.0",
"@solana/sysvars": "^3.0.3",
"@tanstack/react-query": "^5.83.0",
"@token-acl/abl-sdk": "^0.2.0",
Expand All @@ -44,7 +44,7 @@
"immer": "^10.1.1",
"lucide-react": "^0.294.0",
"motion": "^11.11.17",
"next": "15.5.7",
"next": "16.1.0",
"next-themes": "^0.2.1",
"react": "^19.2.1",
"react-dom": "^19.2.1",
Expand All @@ -57,16 +57,20 @@
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.32.0",
"@next/eslint-plugin-next": "^16.1.0",
"@tailwindcss/postcss": "^4.1.17",
"@types/node": "^20.10.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"@typescript-eslint/parser": "^8.46.3",
"autoprefixer": "^10.4.21",
"eslint": "^9.32.0",
"eslint-config-next": "15.5.7",
"eslint-config-next": "16.1.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^16.5.0",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.17",
"typescript": "^5.3.2"
Expand Down
146 changes: 68 additions & 78 deletions apps/app/src/lib/solana/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,77 +120,71 @@ export function createRpcSubscriptions(rpcUrl?: string): RpcSubscriptions<Solana
* @returns Promise with current authorities
*/
export async function getTokenAuthorities(mintAddress: string, rpcUrl?: string): Promise<TokenAuthorities> {
try {
const rpc = createRpcClient(rpcUrl);
const rpc = createRpcClient(rpcUrl);

// Fetch account using @solana/kit like inspect-mint does
const mintAddressTyped = mintAddress as Address;
const encodedAccount = await fetchEncodedAccount(rpc, mintAddressTyped);
// Fetch account using @solana/kit like inspect-mint does
const mintAddressTyped = mintAddress as Address;
const encodedAccount = await fetchEncodedAccount(rpc, mintAddressTyped);

if (!encodedAccount.exists) {
throw new Error('Mint account not found');
}
if (!encodedAccount.exists) {
throw new Error('Mint account not found');
}

// Check if this is a Token-2022 mint
if (encodedAccount.programAddress !== TOKEN_2022_PROGRAM_ADDRESS) {
throw new Error(`Not a Token-2022 mint (owner: ${encodedAccount.programAddress})`);
}
// Check if this is a Token-2022 mint
if (encodedAccount.programAddress !== TOKEN_2022_PROGRAM_ADDRESS) {
throw new Error(`Not a Token-2022 mint (owner: ${encodedAccount.programAddress})`);
}

// Decode mint data using gill's decodeMint
const decodedMint = decodeMint(encodedAccount);

// Extract basic authorities
const authorities: TokenAuthorities = {
mintAuthority:
decodedMint.data.mintAuthority?.__option === 'Some' ? decodedMint.data.mintAuthority.value : undefined,
freezeAuthority:
decodedMint.data.freezeAuthority?.__option === 'Some'
? decodedMint.data.freezeAuthority.value
: undefined,
};

// Extract extension authorities
if (decodedMint.data.extensions && decodedMint.data.extensions.__option === 'Some') {
for (const ext of decodedMint.data.extensions.value) {
if (!ext.__kind) continue;

switch (ext.__kind) {
case 'TokenMetadata':
if ('updateAuthority' in ext && ext.updateAuthority) {
authorities.metadataAuthority =
ext.updateAuthority.__option === 'Some' ? ext.updateAuthority.value : undefined;
}
break;
case 'PermanentDelegate':
if ('delegate' in ext) {
authorities.permanentDelegateAuthority = ext.delegate;
}
break;
case 'ConfidentialTransferMint':
if ('authority' in ext && ext.authority) {
authorities.confidentialBalancesAuthority =
ext.authority.__option === 'Some' ? ext.authority.value : undefined;
}
break;
case 'PausableConfig':
if ('authority' in ext && ext.authority) {
authorities.pausableAuthority =
ext.authority.__option === 'Some' ? ext.authority.value : undefined;
}
break;
case 'ScaledUiAmountConfig':
if ('authority' in ext && ext.authority) {
authorities.scaledUiAmountAuthority = ext.authority;
}
break;
}
// Decode mint data using gill's decodeMint
const decodedMint = decodeMint(encodedAccount);

// Extract basic authorities
const authorities: TokenAuthorities = {
mintAuthority:
decodedMint.data.mintAuthority?.__option === 'Some' ? decodedMint.data.mintAuthority.value : undefined,
freezeAuthority:
decodedMint.data.freezeAuthority?.__option === 'Some' ? decodedMint.data.freezeAuthority.value : undefined,
};

// Extract extension authorities
if (decodedMint.data.extensions && decodedMint.data.extensions.__option === 'Some') {
for (const ext of decodedMint.data.extensions.value) {
if (!ext.__kind) continue;

switch (ext.__kind) {
case 'TokenMetadata':
if ('updateAuthority' in ext && ext.updateAuthority) {
authorities.metadataAuthority =
ext.updateAuthority.__option === 'Some' ? ext.updateAuthority.value : undefined;
}
break;
case 'PermanentDelegate':
if ('delegate' in ext) {
authorities.permanentDelegateAuthority = ext.delegate;
}
break;
case 'ConfidentialTransferMint':
if ('authority' in ext && ext.authority) {
authorities.confidentialBalancesAuthority =
ext.authority.__option === 'Some' ? ext.authority.value : undefined;
}
break;
case 'PausableConfig':
if ('authority' in ext && ext.authority) {
authorities.pausableAuthority =
ext.authority.__option === 'Some' ? ext.authority.value : undefined;
}
break;
case 'ScaledUiAmountConfig':
if ('authority' in ext && ext.authority) {
authorities.scaledUiAmountAuthority = ext.authority;
}
break;
}
}

return authorities;
} catch (error) {
throw error;
}

return authorities;
}

/**
Expand All @@ -202,18 +196,14 @@ export async function getExtensionAuthorities(
_mintAddress: string,
_rpcUrl?: string,
): Promise<Partial<TokenAuthorities>> {
try {
// TODO: Implement extension-specific authority fetching
// This would require fetching each extension's account data
// For now, return empty object as placeholder

return {
metadataAuthority: undefined,
pausableAuthority: undefined,
confidentialBalancesAuthority: undefined,
permanentDelegateAuthority: undefined,
};
} catch (error) {
throw error;
}
// TODO: Implement extension-specific authority fetching
// This would require fetching each extension's account data
// For now, return empty object as placeholder

return {
metadataAuthority: undefined,
pausableAuthority: undefined,
confidentialBalancesAuthority: undefined,
permanentDelegateAuthority: undefined,
};
}
4 changes: 2 additions & 2 deletions apps/app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
Expand All @@ -24,6 +24,6 @@
"@mosaic/sdk": ["../../packages/sdk/src"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
"exclude": ["node_modules"]
}
Loading
Loading