Skip to content

Commit

Permalink
feat: custom network in config
Browse files Browse the repository at this point in the history
  • Loading branch information
krigga committed Feb 15, 2024
1 parent 05bee7c commit 40f3937
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 36 deletions.
7 changes: 6 additions & 1 deletion src/cli/Runner.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import arg from 'arg';
import { UIProvider } from '../ui/UIProvider';
import { Config } from '../config/Config';

export const argSpec = {};

export type Args = arg.Result<typeof argSpec>;

export type Runner = (args: Args, ui: UIProvider) => Promise<void>;
export type RunnerContext = {
config?: Config;
};

export type Runner = (args: Args, ui: UIProvider, context: RunnerContext) => Promise<void>;
9 changes: 6 additions & 3 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { test } from './test';
import { verify } from './verify';
import { additionalHelpMessages, help } from './help';
import { InquirerUIProvider } from '../ui/InquirerUIProvider';
import { argSpec, Runner } from './Runner';
import { argSpec, Runner, RunnerContext } from './Runner';
import path from 'path';
import { Config } from '../config/Config';

Expand All @@ -37,14 +37,17 @@ async function main() {

let effectiveRunners: Record<string, Runner> = {};

const runnerContext: RunnerContext = {};

try {
const configModule = await import(path.join(process.cwd(), 'blueprint.config.ts'));

try {
if ('config' in configModule && typeof configModule.config === 'object') {
const config: Config = configModule.config;
runnerContext.config = config;

for (const plugin of config.plugins) {
for (const plugin of config.plugins ?? []) {
for (const runner of plugin.runners()) {
effectiveRunners[runner.name] = runner.runner;
additionalHelpMessages[runner.name] = runner.help;
Expand Down Expand Up @@ -75,7 +78,7 @@ async function main() {

const ui = new InquirerUIProvider();

await runner(args, ui);
await runner(args, ui, runnerContext);

ui.close();
}
Expand Down
6 changes: 3 additions & 3 deletions src/cli/run.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Args, Runner } from './Runner';
import { Args, Runner, RunnerContext } from './Runner';
import { createNetworkProvider, argSpec } from '../network/createNetworkProvider';
import { findScripts, selectFile } from '../utils';
import { UIProvider } from '../ui/UIProvider';
import arg from 'arg';

export const run: Runner = async (args: Args, ui: UIProvider) => {
export const run: Runner = async (args: Args, ui: UIProvider, context: RunnerContext) => {
const localArgs = arg(argSpec);

const { module: mod } = await selectFile(await findScripts(), {
Expand All @@ -16,7 +16,7 @@ export const run: Runner = async (args: Args, ui: UIProvider) => {
throw new Error('Function `run` is missing!');
}

const networkProvider = await createNetworkProvider(ui, localArgs);
const networkProvider = await createNetworkProvider(ui, localArgs, context.config);

await mod.run(networkProvider, localArgs._.slice(2));
};
6 changes: 3 additions & 3 deletions src/cli/verify.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Address, Cell, Contract, ContractProvider, Dictionary, toNano } from '@ton/core';
import { doCompile } from '../compile/compile';
import { UIProvider } from '../ui/UIProvider';
import { Args, Runner } from './Runner';
import { Args, Runner, RunnerContext } from './Runner';
import path from 'path';
import { argSpec, createNetworkProvider } from '../network/createNetworkProvider';
import { selectCompile } from './build';
Expand Down Expand Up @@ -97,12 +97,12 @@ class VerifierRegistry implements Contract {
}
}

export const verify: Runner = async (args: Args, ui: UIProvider) => {
export const verify: Runner = async (args: Args, ui: UIProvider, context: RunnerContext) => {
const localArgs = arg(argSpec);

const sel = await selectCompile(ui, localArgs);

const networkProvider = await createNetworkProvider(ui, localArgs, false);
const networkProvider = await createNetworkProvider(ui, localArgs, context.config, false);

const sender = networkProvider.sender();

Expand Down
4 changes: 3 additions & 1 deletion src/config/Config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { CustomNetwork } from './CustomNetwork';
import { Plugin } from './Plugin';

export interface Config {
plugins: Plugin[];
plugins?: Plugin[];
network?: 'mainnet' | 'testnet' | CustomNetwork;
}
6 changes: 6 additions & 0 deletions src/config/CustomNetwork.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type CustomNetwork = {
endpoint: string;
version?: 'v2' | 'v4';
key?: string;
type?: 'mainnet' | 'testnet' | 'custom';
};
84 changes: 59 additions & 25 deletions src/network/createNetworkProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import path from 'path';
import { TEMP_DIR } from '../paths';
import { mnemonicToPrivateKey } from '@ton/crypto';
import { MnemonicProvider, WalletVersion } from './send/MnemonicProvider';
import { Config } from '../config/Config';
import { CustomNetwork } from '../config/CustomNetwork';

export const argSpec = {
'--mainnet': Boolean,
Expand Down Expand Up @@ -261,6 +263,7 @@ class NetworkProviderBuilder {
constructor(
private args: Args,
private ui: UIProvider,
private config?: Config,
private allowCustom = true,
) {}

Expand All @@ -271,19 +274,21 @@ class NetworkProviderBuilder {
custom: this.args['--custom'] !== undefined,
});

if (!network) {
network = await this.ui.choose(
'Which network do you want to use?',
['mainnet', 'testnet', 'custom'],
(c) => c,
);
if (network === 'custom') {
const defaultCustomEndpoint = 'http://localhost:8081/';
this.args['--custom'] = (
await this.ui.input(`Provide a custom API v2 endpoint (default is ${defaultCustomEndpoint})`)
).trim();
if (this.args['--custom'] === '') this.args['--custom'] = defaultCustomEndpoint;
}
if (network !== undefined) {
return network;
}

if (this.config?.network !== undefined) {
return typeof this.config.network === 'string' ? this.config.network : 'custom';
}

network = await this.ui.choose('Which network do you want to use?', ['mainnet', 'testnet', 'custom'], (c) => c);
if (network === 'custom') {
const defaultCustomEndpoint = 'http://localhost:8081/';
this.args['--custom'] = (
await this.ui.input(`Provide a custom API v2 endpoint (default is ${defaultCustomEndpoint})`)
).trim();
if (this.args['--custom'] === '') this.args['--custom'] = defaultCustomEndpoint;
}

return network;
Expand Down Expand Up @@ -375,25 +380,49 @@ class NetworkProviderBuilder {

let tc;
if (network === 'custom') {
const endpoint = this.args['--custom']!;
if (this.args['--custom-version'] === undefined || this.args['--custom-version'].toLowerCase() === 'v2') {
let configNetwork: CustomNetwork | undefined = undefined;
if (this.config?.network !== undefined && typeof this.config.network !== 'string') {
configNetwork = this.config.network;
}
if (this.args['--custom'] !== undefined) {
const inputVer = this.args['--custom-version'];
let version: 'v4' | 'v2' | undefined = undefined;
if (inputVer !== undefined) {
version = inputVer.toLowerCase() as any; // checks come later
}
const inputType = this.args['--custom-type'];
let type: 'mainnet' | 'testnet' | 'custom' | undefined = undefined;
if (inputType !== undefined) {
type = inputType as any; // checks come later
}
configNetwork = {
endpoint: this.args['--custom'],
version,
key: this.args['--custom-key'],
type,
};
}
if (configNetwork === undefined) {
throw new Error('Custom network is (somehow) undefined');
}
if (configNetwork.version === undefined || configNetwork.version === 'v2') {
tc = new TonClient({
endpoint: endpoint + 'jsonRPC',
apiKey: this.args['--custom-key'],
endpoint: configNetwork.endpoint + 'jsonRPC',
apiKey: configNetwork.key,
});
} else if (this.args['--custom-version'].toLowerCase() === 'v4') {
if (this.args['--custom-key'] !== undefined) {
} else if (configNetwork.version === 'v4') {
if (configNetwork.key !== undefined) {
throw new Error('Cannot use a custom API key with a v4 API');
}
tc = new TonClient4({
endpoint,
endpoint: configNetwork.endpoint,
});
} else {
throw new Error('Unknown API version: ' + this.args['--custom-version']);
throw new Error('Unknown API version: ' + configNetwork.version);
}

if (this.args['--custom-type'] !== undefined) {
const ct = this.args['--custom-type'].toLowerCase();
if (configNetwork.type !== undefined) {
const ct = configNetwork.type.toLowerCase();
if (!['mainnet', 'testnet', 'custom'].includes(ct)) {
throw new Error('Unknown network type: ' + ct);
}
Expand Down Expand Up @@ -424,6 +453,11 @@ class NetworkProviderBuilder {
}
}

export async function createNetworkProvider(ui: UIProvider, args: Args, allowCustom = true): Promise<NetworkProvider> {
return await new NetworkProviderBuilder(args, ui, allowCustom).build();
export async function createNetworkProvider(
ui: UIProvider,
args: Args,
config?: Config,
allowCustom = true,
): Promise<NetworkProvider> {
return await new NetworkProviderBuilder(args, ui, config, allowCustom).build();
}

0 comments on commit 40f3937

Please sign in to comment.