Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookbook v2 snippets #625

Merged
merged 5 commits into from
Nov 19, 2024
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
39 changes: 16 additions & 23 deletions content/cookbook/accounts/calculate-rent.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,15 @@ account. Rent can be reclaimed in full if the account is closed.

<Tab value="web3.js v2">

```typescript
```typescript filename="calculate-rent.ts"
import { createSolanaRpc } from "@solana/web3.js";

(async () => {
const rpc = createSolanaRpc("https://api.devnet.solana.com");
// length of data in bytes in the account to calculate rent for
const dataLength = 1500;
const rentExemptionAmount = await rpc
.getMinimumBalanceForRentExemption(BigInt(dataLength))
.send();
console.log({
rentExemptionAmount,
});
})();
const rpc = createSolanaRpc("https://api.devnet.solana.com");
// 1.5k bytes
const space = 1500n;

const lamports = await rpc.getMinimumBalanceForRentExemption(space).send();
console.log("Minimum balance for rent exception:", lamports);
```

</Tab>
Expand All @@ -37,17 +32,15 @@ import { createSolanaRpc } from "@solana/web3.js";
```typescript
import { Connection, clusterApiUrl } from "@solana/web3.js";

(async () => {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// length of data in bytes in the account to calculate rent for
const dataLength = 1500;
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(dataLength);
console.log({
rentExemptionAmount,
});
})();
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// length of data in bytes in the account to calculate rent for
const dataLength = 1500;
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(dataLength);
console.log({
rentExemptionAmount,
});
```

</Tab>
Expand Down
168 changes: 128 additions & 40 deletions content/cookbook/accounts/create-account.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,96 @@ description:
---

Creating an account requires using the System Program `createAccount`
instruction. The Solana runtime will grant the owner of an account, access to
write to its data or transfer lamports. When creating an account, we have to
preallocate a fixed storage space in bytes (space) and enough lamports to cover
the rent.
instruction. The Solana runtime will grant the owner program of an account,
access to write to its data or transfer lamports. When creating an account, we
have to preallocate a fixed storage space in bytes (space) and enough lamports
to cover the rent.

<Tabs groupId="language" items={['web3.js v2', 'web3.js v1']}>

<Tab value="web3.js v2">

```typescript filename="create-account.ts"
import {
pipe,
createSolanaRpc,
appendTransactionMessageInstructions,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners,
} from "@solana/web3.js";
import { getSetComputeUnitPriceInstruction } from "@solana-program/compute-budget";
import {
getCreateAccountInstruction,
SYSTEM_PROGRAM_ADDRESS,
} from "@solana-program/system";

const rpc = createSolanaRpc("https://api.devnet.solana.com");
const rpcSubscriptions = createSolanaRpcSubscriptions(
"wss://api.devnet.solana.com",
);

const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
rpc,
rpcSubscriptions,
});

const space = 0n; // any extra space in the account
const rentLamports = await rpc.getMinimumBalanceForRentExemption(space).send();
console.log("Minimum balance for rent exception:", rentLamports);

// todo: load your own signer with SOL
const signer = await generateKeyPairSigner();

// generate a new keypair and address to create
const newAccountKeypair = await generateKeyPairSigner();
console.log("New account address:", newAccountKeypair.address);

const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

const transactionMessage = pipe(
createTransactionMessage({ version: "legacy" }),
tx => setTransactionMessageFeePayerSigner(signer, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx =>
appendTransactionMessageInstructions(
[
// add a priority fee
getSetComputeUnitPriceInstruction({
microLamports: 200_000,
}),
// create the new account
getCreateAccountInstruction({
lamports: rentLamports,
newAccount: newAccountKeypair,
payer: signer,
space: space,
// "wallet" accounts are owned by the system program
programAddress: SYSTEM_PROGRAM_ADDRESS,
}),
],
tx,
),
);

const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
const signature = getSignatureFromTransaction(signedTransaction);

await sendAndConfirmTransaction(signedTransaction, {
commitment: "confirmed",
});
console.log("Signature:", signature);
```

</Tab>

<Tab value="web3.js v1">

```typescript filename="create-account.ts"
import {
Expand All @@ -23,40 +109,42 @@ import {
LAMPORTS_PER_SOL,
} from "@solana/web3.js";

(async () => {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const fromPubkey = Keypair.generate();

// Airdrop SOL for transferring lamports to the created account
const airdropSignature = await connection.requestAirdrop(
fromPubkey.publicKey,
LAMPORTS_PER_SOL,
);
await connection.confirmTransaction(airdropSignature);

// amount of space to reserve for the account
const space = 0;

// Seed the created account with lamports for rent exemption
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(space);

const newAccountPubkey = Keypair.generate();
const createAccountParams = {
fromPubkey: fromPubkey.publicKey,
newAccountPubkey: newAccountPubkey.publicKey,
lamports: rentExemptionAmount,
space,
programId: SystemProgram.programId,
};

const createAccountTransaction = new Transaction().add(
SystemProgram.createAccount(createAccountParams),
);

await sendAndConfirmTransaction(connection, createAccountTransaction, [
fromPubkey,
newAccountPubkey,
]);
})();
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const fromPubkey = Keypair.generate();

// Airdrop SOL for transferring lamports to the created account
const airdropSignature = await connection.requestAirdrop(
fromPubkey.publicKey,
LAMPORTS_PER_SOL,
);
await connection.confirmTransaction(airdropSignature);

// amount of space to reserve for the account
const space = 0;

// Seed the created account with lamports for rent exemption
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(space);

const newAccountPubkey = Keypair.generate();
const createAccountParams = {
fromPubkey: fromPubkey.publicKey,
newAccountPubkey: newAccountPubkey.publicKey,
lamports: rentExemptionAmount,
space,
programId: SystemProgram.programId,
};

const createAccountTransaction = new Transaction().add(
SystemProgram.createAccount(createAccountParams),
);

await sendAndConfirmTransaction(connection, createAccountTransaction, [
fromPubkey,
newAccountPubkey,
]);
```

</Tab>

</Tabs>
36 changes: 28 additions & 8 deletions content/cookbook/accounts/get-account-balance.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,40 @@ description:
that account balance on Solana."
---

```typescript filename="get-account-balance.ts" {13}
<Tabs groupId="language" items={['web3.js v2', 'web3.js v1']}>

<Tab value="web3.js v2">

```typescript filename="get-account-balance.ts"
import { address, createSolanaRpc } from "@solana/web3.js";

const rpc = createSolanaRpc("https://api.devnet.solana.com");
const LAMPORTS_PER_SOL = 1_000_000_000; // 1 billion lamports per SOL

const wallet = address("nicktrLHhYzLmoVbuZQzHUTicd2sfP571orwo9jfc8c");
const { value: balance } = await rpc.getBalance(wallet).send();
console.log(`Balance: ${Number(balance) / LAMPORTS_PER_SOL} SOL`);
```

</Tab>

<Tab value="web3.js v1">

```typescript filename="get-account-balance.ts"
import {
clusterApiUrl,
Connection,
PublicKey,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";

(async () => {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const wallet = new PublicKey("nicktrLHhYzLmoVbuZQzHUTicd2sfP571orwo9jfc8c");

let wallet = new PublicKey("G2FAbFQPFa5qKXCetoFZQEvF9BVvCKbvUZvodpVidnoY");
console.log(
`${(await connection.getBalance(wallet)) / LAMPORTS_PER_SOL} SOL`,
);
})();
const balance = await connection.getBalance(wallet);
console.log(`Balance: ${balance / LAMPORTS_PER_SOL} SOL`);
```

</Tab>

</Tabs>
3 changes: 2 additions & 1 deletion content/courses/tokens-and-nfts/nfts-with-metaplex.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@ To begin, make a new folder and install the relevant dependencies:
npm i @solana/web3.js@1 @solana-developers/helpers@2 @metaplex-foundation/mpl-token-metadata @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/umi-uploader-irys esrun
```

Then create a file called `create-metaplex-nft-collection.ts`, and add our imports:
Then create a file called `create-metaplex-nft-collection.ts`, and add our
imports:

```typescript
import {
Expand Down
17 changes: 9 additions & 8 deletions docs/core/clusters.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,18 @@ An example of some of these Solana blockchain explorers include:
## On a high level

- Mainnet: Live production environment for deployed applications.
- Devnet: Testing with public accessibility for developers experimenting with their applications.
- Devnet: Testing with public accessibility for developers experimenting with
their applications.
- Testnet: Stress-testing for network upgrades and validator performance.

**Example use cases**: You may want to debug a new program on Devnet or verify performance metrics on Testnet before Mainnet deployment.

| **Cluster** | **Endpoint** | **Purpose** | **Notes** |
|---------------|----------------------------------|---------------------------------------------|-------------------------------------|
| Mainnet | `https://api.mainnet-beta.solana.com` | Live production environment | Requires SOL for transactions |
| Devnet | `https://api.devnet.solana.com` | Public testing and development | Free SOL airdrop for testing |
| Testnet | `https://api.testnet.solana.com` | Validator and stress testing | May have intermittent downtime |
**Example use cases**: You may want to debug a new program on Devnet or verify
performance metrics on Testnet before Mainnet deployment.

| **Cluster** | **Endpoint** | **Purpose** | **Notes** |
| ----------- | ------------------------------------- | ------------------------------ | ------------------------------ |
| Mainnet | `https://api.mainnet-beta.solana.com` | Live production environment | Requires SOL for transactions |
| Devnet | `https://api.devnet.solana.com` | Public testing and development | Free SOL airdrop for testing |
| Testnet | `https://api.testnet.solana.com` | Validator and stress testing | May have intermittent downtime |

## Devnet

Expand Down