Skip to content

Commit

Permalink
Add a cli option to adjust priority fees. (#254)
Browse files Browse the repository at this point in the history
* Create an optional argument to set priority fees.

* Fix test

* Add checks for negative priority fee.

* Extract default priority fee as constant
  • Loading branch information
ankur2136 authored Apr 9, 2024
1 parent 9a1a579 commit 4a68853
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 44 deletions.
17 changes: 11 additions & 6 deletions packages/cli/src/CliSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function resolveBuildToolsPath(buildToolsPath: string | undefined) {
function latestReleaseMessage() {
showMessage(
`Publishing Tools Version ${ Constants.CLI_VERSION }`,
"- priority fee has been updated to handle network congestion\n- short_description value reduced to 30 character limit",
`- priority fee has been updated to ${Constants.DEFAULT_PRIORITY_FEE} lamports = ${Constants.DEFAULT_PRIORITY_FEE/1000000000} SOL. To adjust this value use param "-p or --priority-fee-lamports"`,
"warning"
);
}
Expand Down Expand Up @@ -94,14 +94,15 @@ export const createPublisherCliCmd = createCliCmd
.option("-u, --url <url>", "RPC URL", Constants.DEFAULT_RPC_DEVNET)
.option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
.option("-s, --storage-config <storage-config>", "Provide alternative storage configuration details")
.action(async ({ keypair, url, dryRun, storageConfig }) => {
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
.action(async ({ keypair, url, dryRun, storageConfig, priorityFeeLamports }) => {
await tryWithErrorMessage(async () => {
latestReleaseMessage();
await checkForSelfUpdate();

const signer = parseKeypair(keypair);
if (signer) {
const result: { publisherAddress: string } = await createPublisherCommand({ signer, url, dryRun, storageParams: storageConfig });
const result: { publisherAddress: string } = await createPublisherCommand({ signer, url, dryRun, storageParams: storageConfig, priorityFeeLamports });

const displayUrl = `https://solscan.io/token/${result.publisherAddress}${generateNetworkSuffix(url)}`;
const resultText = `Publisher NFT successfully minted:\n${displayUrl}`;
Expand All @@ -125,7 +126,8 @@ export const createAppCliCmd = createCliCmd
.option("-u, --url <url>", "RPC URL", Constants.DEFAULT_RPC_DEVNET)
.option("-d, --dry-run", "Flag for dry run. Doesn't mint an NFT")
.option("-s, --storage-config <storage-config>", "Provide alternative storage configuration details")
.action(async ({ publisherMintAddress, keypair, url, dryRun, storageConfig }) => {
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
.action(async ({ publisherMintAddress, keypair, url, dryRun, storageConfig, priorityFeeLamports }) => {
await tryWithErrorMessage(async () => {
latestReleaseMessage();
await checkForSelfUpdate();
Expand All @@ -143,7 +145,8 @@ export const createAppCliCmd = createCliCmd
signer,
url,
dryRun,
storageParams: storageConfig
storageParams: storageConfig,
priorityFeeLamports: priorityFeeLamports,
});

const displayUrl = `https://solscan.io/token/${result.appAddress}${generateNetworkSuffix(url)}`;
Expand Down Expand Up @@ -172,7 +175,8 @@ export const createReleaseCliCmd = createCliCmd
"Path to Android build tools which contains AAPT2"
)
.option("-s, --storage-config <storage-config>", "Provide alternative storage configuration details")
.action(async ({ appMintAddress, keypair, url, dryRun, buildToolsPath, storageConfig }) => {
.option("-p, --priority-fee-lamports <priority-fee-lamports>", "Priority Fee lamports")
.action(async ({ appMintAddress, keypair, url, dryRun, buildToolsPath, storageConfig, priorityFeeLamports }) => {
await tryWithErrorMessage(async () => {
latestReleaseMessage();
await checkForSelfUpdate();
Expand All @@ -196,6 +200,7 @@ export const createReleaseCliCmd = createCliCmd
url,
dryRun,
storageParams: storageConfig,
priorityFeeLamports: priorityFeeLamports
});

const displayUrl = `https://solscan.io/token/${result?.releaseAddress}${generateNetworkSuffix(url)}`;
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/CliUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class Constants {
static CLI_VERSION = "0.7.3";
static CONFIG_FILE_NAME = "config.yaml";
static DEFAULT_RPC_DEVNET = "https://api.devnet.solana.com";
static DEFAULT_PRIORITY_FEE = 500000;

static getConfigFilePath = () => {
return `${process.cwd()}/${Constants.CONFIG_FILE_NAME}`;
Expand Down
27 changes: 15 additions & 12 deletions packages/cli/src/__tests__/CliSetupTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,12 @@ Commands:
Create a publisher
Options:
-k, --keypair <path-to-keypair-file> Path to keypair file
-u, --url <url> RPC URL (default: "https://api.devnet.solana.com")
-d, --dry-run Flag for dry run. Doesn't mint an NFT
-s, --storage-config <storage-config> Provide alternative storage configuration details
-h, --help display help for command
-k, --keypair <path-to-keypair-file> Path to keypair file
-u, --url <url> RPC URL (default: "https://api.devnet.solana.com")
-d, --dry-run Flag for dry run. Doesn't mint an NFT
-s, --storage-config <storage-config> Provide alternative storage configuration details
-p, --priority-fee-lamports <priority-fee-lamports> Priority Fee lamports
-h, --help display help for command
`;

const createAppHelp = `Usage: dapp-store create app [options]
Expand All @@ -192,6 +193,7 @@ Options:
-u, --url <url> RPC URL (default: "https://api.devnet.solana.com")
-d, --dry-run Flag for dry run. Doesn't mint an NFT
-s, --storage-config <storage-config> Provide alternative storage configuration details
-p, --priority-fee-lamports <priority-fee-lamports> Priority Fee lamports
-h, --help display help for command
`;

Expand All @@ -200,13 +202,14 @@ Options:
Create a release
Options:
-k, --keypair <path-to-keypair-file> Path to keypair file
-a, --app-mint-address <app-mint-address> The mint address of the app NFT
-u, --url <url> RPC URL (default: "https://api.devnet.solana.com")
-d, --dry-run Flag for dry run. Doesn't mint an NFT
-b, --build-tools-path <build-tools-path> Path to Android build tools which contains AAPT2
-s, --storage-config <storage-config> Provide alternative storage configuration details
-h, --help display help for command
-k, --keypair <path-to-keypair-file> Path to keypair file
-a, --app-mint-address <app-mint-address> The mint address of the app NFT
-u, --url <url> RPC URL (default: "https://api.devnet.solana.com")
-d, --dry-run Flag for dry run. Doesn't mint an NFT
-b, --build-tools-path <build-tools-path> Path to Android build tools which contains AAPT2
-s, --storage-config <storage-config> Provide alternative storage configuration details
-p, --priority-fee-lamports <priority-fee-lamports> Priority Fee lamports
-h, --help display help for command
`;

});
7 changes: 7 additions & 0 deletions packages/cli/src/commands/create/CreateCliApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "@solana/web3.js";

import {
Constants,
getMetaplexInstance,
} from "../../CliUtils.js";
import { loadPublishDetailsWithChecks, writeToPublishDetails } from "../../config/PublishDetails.js";
Expand All @@ -19,12 +20,14 @@ const createAppNft = async (
publisherMintAddress,
publisher,
storageParams,
priorityFeeLamports,
}: {
appDetails: App;
connection: Connection;
publisherMintAddress: string;
publisher: Keypair;
storageParams: string;
priorityFeeLamports: number;
},
{ dryRun }: { dryRun?: boolean }
) => {
Expand All @@ -35,6 +38,7 @@ const createAppNft = async (
publisherMintAddress: new PublicKey(publisherMintAddress),
mintAddress,
appDetails,
priorityFeeLamports
},
{ metaplex, publisher }
);
Expand Down Expand Up @@ -62,6 +66,7 @@ type CreateAppCommandInput = {
url: string;
dryRun?: boolean;
storageParams: string;
priorityFeeLamports: number;
};

export const createAppCommand = async ({
Expand All @@ -70,6 +75,7 @@ export const createAppCommand = async ({
dryRun,
publisherMintAddress,
storageParams,
priorityFeeLamports = Constants.DEFAULT_PRIORITY_FEE,
}: CreateAppCommandInput) => {
const connection = new Connection(url);

Expand All @@ -83,6 +89,7 @@ export const createAppCommand = async ({
publisherMintAddress: publisherDetails.address ?? publisherMintAddress,
appDetails,
storageParams,
priorityFeeLamports
},
{ dryRun }
);
Expand Down
8 changes: 7 additions & 1 deletion packages/cli/src/commands/create/CreateCliPublisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "@solana/web3.js";

import {
Constants,
getMetaplexInstance,
} from "../../CliUtils.js";
import { loadPublishDetailsWithChecks, writeToPublishDetails } from "../../config/PublishDetails.js";
Expand All @@ -17,11 +18,13 @@ const createPublisherNft = async (
publisher,
publisherDetails,
storageParams,
priorityFeeLamports,
}: {
connection: Connection;
publisher: Keypair;
publisherDetails: Publisher;
storageParams: string;
priorityFeeLamports: number;
},
{ dryRun }: { dryRun: boolean }
) => {
Expand All @@ -31,7 +34,7 @@ const createPublisherNft = async (
`Creating publisher at address: ${mintAddress.publicKey.toBase58()}`
);
const txBuilder = await createPublisher(
{ mintAddress, publisherDetails },
{ mintAddress, publisherDetails, priorityFeeLamports },
{ metaplex, publisher }
);

Expand All @@ -57,11 +60,13 @@ export const createPublisherCommand = async ({
url,
dryRun,
storageParams,
priorityFeeLamports = Constants.DEFAULT_PRIORITY_FEE,
}: {
signer: Keypair;
url: string;
dryRun: boolean;
storageParams: string;
priorityFeeLamports: number;
}) => {
const connection = new Connection(url);

Expand All @@ -73,6 +78,7 @@ export const createPublisherCommand = async ({
publisher: signer,
publisherDetails,
storageParams: storageParams,
priorityFeeLamports: priorityFeeLamports,
},
{ dryRun }
);
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/src/commands/create/CreateCliRelease.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
Constants,
getMetaplexInstance,
showMessage
} from "../../CliUtils.js";
Expand All @@ -23,6 +24,7 @@ type CreateReleaseCommandInput = {
url: string;
dryRun?: boolean;
storageParams: string;
priorityFeeLamports: number;
};

const createReleaseNft = async ({
Expand All @@ -33,6 +35,7 @@ const createReleaseNft = async ({
connection,
publisher,
storageParams,
priorityFeeLamports,
}: {
appMintAddress: string;
releaseDetails: Release;
Expand All @@ -41,6 +44,7 @@ const createReleaseNft = async ({
connection: Connection;
publisher: Keypair;
storageParams: string;
priorityFeeLamports: number;
}) => {
const releaseMintAddress = Keypair.generate();

Expand All @@ -53,6 +57,7 @@ const createReleaseNft = async ({
releaseDetails,
appDetails,
publisherDetails,
priorityFeeLamports
},
{ metaplex, publisher }
);
Expand Down Expand Up @@ -94,6 +99,7 @@ export const createReleaseCommand = async ({
url,
dryRun = false,
storageParams,
priorityFeeLamports = Constants.DEFAULT_PRIORITY_FEE,
}: CreateReleaseCommandInput) => {
const connection = new Connection(url);

Expand All @@ -110,6 +116,7 @@ export const createReleaseCommand = async ({
appDetails: app,
publisherDetails: publisher,
storageParams: storageParams,
priorityFeeLamports: priorityFeeLamports,
});

await writeToPublishDetails({ release: { address: releaseAddress }, });
Expand Down
14 changes: 11 additions & 3 deletions packages/core/src/CoreUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ type JsonMetadataMetaplexFile = Omit<JsonMetadata, "image"> & {
export const mintNft = async (
metaplex: Metaplex,
json: JsonMetadataMetaplexFile,
createNftInput: Omit<CreateNftInput, "uri" | "name" | "sellerFeeBasisPoints">
createNftInput: Omit<CreateNftInput, "uri" | "name" | "sellerFeeBasisPoints">,
priorityFeeLamports: number,
): Promise<TransactionBuilder> => {
console.info({ json });
const { uri } = await metaplex.nfts().uploadMetadata(json);
const computeBudget = 250000

if (priorityFeeLamports < 0) {
throw new Error("Priority fees cannot be negative")
}

const txBuilder = await metaplex
.nfts()
Expand All @@ -42,14 +48,16 @@ export const mintNft = async (

txBuilder.prepend({
instruction: ComputeBudgetProgram.setComputeUnitLimit({
units: 250000,
units: computeBudget,
}),
signers: [],
});

const microLamportsPerCU = 1000000 * priorityFeeLamports / computeBudget

txBuilder.prepend({
instruction: ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 2000000,
microLamports: microLamportsPerCU,
}),
signers: [],
});
Expand Down
24 changes: 15 additions & 9 deletions packages/core/src/create/AppCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,31 @@ type CreateAppInput = {
publisherMintAddress: PublicKey;
mintAddress: Signer;
appDetails: App;
priorityFeeLamports: number;
};

export const createApp = async (
{ publisherMintAddress, mintAddress, appDetails }: CreateAppInput,
{ publisherMintAddress, mintAddress, appDetails, priorityFeeLamports }: CreateAppInput,
{ metaplex, publisher }: Context
) => {
debug(`Minting app NFT for publisher: ${publisherMintAddress.toBase58()}`);

const appJson = createAppJson(appDetails, publisher.publicKey);
validateApp(appJson);

const txBuilder = await mintNft(metaplex, appJson, {
useNewMint: mintAddress,
collection: publisherMintAddress,
collectionAuthority: publisher,
isCollection: true,
isMutable: true,
creators: [{ address: publisher.publicKey, share: 100 }],
});
const txBuilder = await mintNft(
metaplex,
appJson,
{
useNewMint: mintAddress,
collection: publisherMintAddress,
collectionAuthority: publisher,
isCollection: true,
isMutable: true,
creators: [{ address: publisher.publicKey, share: 100 }],
},
priorityFeeLamports
);

txBuilder.append(
metaplex.nfts().builders().verifyCreator({
Expand Down
18 changes: 12 additions & 6 deletions packages/core/src/create/PublisherCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,28 @@ export const createPublisherJson = (
type CreatePublisherInput = {
mintAddress: Signer;
publisherDetails: Publisher;
priorityFeeLamports: number;
};

export const createPublisher = async (
{ mintAddress, publisherDetails }: CreatePublisherInput,
{ mintAddress, publisherDetails, priorityFeeLamports }: CreatePublisherInput,
{ metaplex }: Context
): Promise<TransactionBuilder> => {
debug(`Minting publisher NFT`);

const publisherJson = createPublisherJson(publisherDetails);
validatePublisher(publisherJson);

const txBuilder = await mintNft(metaplex, publisherJson, {
isCollection: true,
isMutable: true,
useNewMint: mintAddress,
});
const txBuilder = await mintNft(
metaplex,
publisherJson,
{
isCollection: true,
isMutable: true,
useNewMint: mintAddress,
},
priorityFeeLamports
);

return txBuilder;
};
Loading

0 comments on commit 4a68853

Please sign in to comment.