You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/basics/cpi.mdx
+3-31Lines changed: 3 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,14 +48,14 @@ A CPI is constructed the same way as any other Solana instruction. The caller mu
48
48
49
49
The System Program's `transfer(){:rs}` instruction requires a `from{:rs}` account that sends the SOL and a `to{:rs}` account that receives it. The `SolTransfer{:rs}` struct declares both accounts plus the System Program itself, since the CPI invokes that program:
The first approach uses Anchor's [`CpiContext`](https://docs.rs/anchor-lang/latest/anchor_lang/context/struct.CpiContext.html), which bundles the `program_id{:rs}` and accounts required by the instruction. The `cpi_context{:rs}` is then passed to the `transfer(){:rs}` helper to invoke the instruction:
58
+
The first approach uses Anchor's [`CpiContext{:rs}`](https://docs.rs/anchor-lang/latest/anchor_lang/context/struct.CpiContext.html), which bundles the `program_id{:rs}` and accounts required by the instruction. The `cpi_context{:rs}` is then passed to the `transfer(){:rs}` helper to invoke the instruction:
The first approach uses [`CpiContext`](https://docs.rs/anchor-lang/latest/anchor_lang/context/struct.CpiContext.html), then attaches the signer seeds via `with_signer(){:rs}`:
204
+
The first approach uses [`CpiContext{:rs}`](https://docs.rs/anchor-lang/latest/anchor_lang/context/struct.CpiContext.html), then attaches the signer seeds via `with_signer(){:rs}`:
@@ -213,31 +213,3 @@ When the CPI executes, the Solana runtime validates that the supplied seeds and
213
213
<Tab>
214
214
215
215
The first approach is a wrapper around `invoke_signed(){:rs}` paired with `system_instruction::transfer(){:rs}`. Calling `invoke_signed(){:rs}` directly produces an equivalent CPI:
The `signer_seeds{:rs}` are passed into `invoke_signed(){:rs}` as the third argument.
239
-
240
-
</Tab>
241
-
</Tabs>
242
-
243
-
A reference program containing both approaches is available on [Solana Playground](https://beta.solpg.io/github.com/ZYJLiu/doc-examples/tree/main/cpi-pda).
See the [account discriminator source](https://github.com/solana-foundation/anchor/blob/62865c636aecc6974fc9cfebfc6cf08ca4f0bb72/lang/attribute/account/src/lib.rs#L113-L125) for the implementation.
167
-
168
-
<Calloutvariant="note">
169
-
Two programs that define accounts with the same struct name produce identical discriminators. Anchor avoids confusion at deserialization time by also verifying that the account is owned by the expected program.
The `init{:rs}` constraint is commonly used with `seeds{:rs}` and `bump{:rs}` to create a new account whose address is a PDA. Under the hood, `init{:rs}` invokes the System Program to create the account:
143
-
144
-
```rust showLineNumbers=false {5-7}
145
-
#[derive(Accounts)]
146
-
pubstructInstructionAccounts<'info> {
147
-
#[account(mut)]
148
-
pubsigner:Signer<'info>,
149
-
#[account(
150
-
init,
151
-
payer = signer,
152
-
space = 8 + 1,
153
-
seeds = [b"hello_world", signer.key().as_ref()],
154
-
bump,
155
-
)]
156
-
pubpda_account:Account<'info, CustomAccount>,
157
-
pubsystem_program:Program<'info, System>,
158
-
}
159
-
160
-
#[account]
161
-
pubstructCustomAccount {
162
-
pubbump_seed:u8,
163
-
}
164
-
```
165
-
166
-
<Calloutvariant="note">
167
-
The `init{:rs}` constraint must be used with `payer{:rs}` and `space{:rs}`. The `payer{:rs}` specifies the account that will pay for the account creation. The `space{:rs}` specifies the bytes to allocate for the account (including the 8-byte discriminator).
168
-
</Callout>
169
-
170
-
</Tab>
171
-
</Tabs>
172
-
173
-
## PDA seeds in the IDL
174
-
175
-
PDA seeds defined in the `seeds{:rs}` constraint are included in the program's IDL file. This allows the Anchor client to automatically resolve account addresses using these seeds when constructing instructions.
176
-
177
-
<Tabsitems={['Program', 'IDL', 'Client']}>
178
-
<Tab>
179
-
180
-
The program below defines a `pda_account{:rs}` using a static seed (`b"hello_world"{:rs}`) and the signer's public key as a dynamic seed:
The IDL records the PDA seeds declared on the account. The static seed `b"hello_world"{:rs}` is converted to byte values, and the dynamic seed is included as a reference to the signer account:
The Anchor client uses the IDL to automatically resolve the PDA address. The provider wallet acts as the signer, and its public key becomes the dynamic seed for derivation, so the client can call the instruction without explicitly deriving the PDA:
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/basics/program-structure.mdx
+1-7Lines changed: 1 addition & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ The following program exposes a single `initialize(){:rs}` instruction that crea
23
23
24
24
The [`declare_id!(){:rs}`](https://docs.rs/anchor-lang/latest/anchor_lang/macro.declare_id.html) macro embeds the program's on-chain address, known as the program ID, into the compiled binary:
By default, the program ID is the public key of the keypair at `/target/deploy/<program_name>-keypair.json`. To rewrite the `declare_id!(){:rs}` string to match the on-disk keypair, run `$ [34manchor[0m keys sync{:ansi}`.
29
29
@@ -100,9 +100,3 @@ The discriminator is the first 8 bytes of `SHA256("account:<StructName>"){:rs}`,
Every `init{:rs}` constraint must allocate 8 extra bytes of space for the discriminator in addition to the account's own fields. In the example below, `space = 8 + 8{:rs}` covers 8 bytes for the discriminator plus 8 bytes for the `data: u64{:rs}` field.
The example below uses `@anchor-lang/core` to interact with a simple Anchor program. The program exposes an `initialize{:rs}` instruction that creates and initializes a counter account, and an `increment{:rs}` instruction that increments the stored value.
270
-
271
-
<Codecode={lib}lang="rust"title="lib.rs" />
272
-
273
-
A typical folder layout for a TypeScript client that interacts with the program looks like this:
274
-
275
-
<FileTree>
276
-
<Dirname="ts"open={true}>
277
-
<Dirname="idl"open={true}>
278
-
<Filename="example.json" />
279
-
<Filename="example.ts" />
280
-
</Dir>
281
-
<Filename="example.ts" />
282
-
<Filename="package.json" />
283
-
</Dir>
284
-
</FileTree>
285
-
286
-
The `/idl` directory contains the IDL itself in `example.json` and a generated TypeScript type definition in `example.ts`. Both files are reproduced below for reference:
Running `$ [34manchor[0m build{:ansi}` in an Anchor project regenerates both files automatically: the IDL file at `target/idl/<program-name>.json` (e.g., `target/idl/example.json`) and the TypeScript type definitions at `target/types/<program-name>.ts` (e.g., `target/types/example.ts`).
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/features/errors.mdx
-51Lines changed: 0 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -116,54 +116,3 @@ pub enum MyError {
116
116
### `require!(){:rs}`
117
117
118
118
The [`require!(){:rs}`](https://docs.rs/anchor-lang/latest/anchor_lang/macro.require.html) macro provides a more concise way to handle error conditions. It combines a condition check with returning an error if the condition is false:
Anchor provides several `require{:rs}` macros for different validation needs:
139
-
140
-
-`require!(){:rs}` ensures a condition is true, otherwise returns the given error.
141
-
-`require_eq!(){:rs}` ensures two non-pubkey values are equal.
142
-
-`require_neq!(){:rs}` ensures two non-pubkey values are not equal.
143
-
-`require_keys_eq!(){:rs}` ensures two pubkeys are equal.
144
-
-`require_keys_neq!(){:rs}` ensures two pubkeys are not equal.
145
-
-`require_gt!(){:rs}` ensures the first non-pubkey value is greater than the second.
146
-
-`require_gte!(){:rs}` ensures the first non-pubkey value is greater than or equal to the second.
147
-
148
-
## Example
149
-
150
-
The program below validates that an input amount falls within an acceptable range. It defines two custom error variants with messages and uses `require!(){:rs}` to enforce the bounds:
When a program error occurs, Anchor's TypeScript client SDK returns a detailed [error response](https://github.com/solana-foundation/anchor/blob/62865c636aecc6974fc9cfebfc6cf08ca4f0bb72/ts/packages/anchor/src/error.ts#L51-L71) containing information about the error:
For a more comprehensive example, see the [errors test program](https://github.com/solana-foundation/anchor/blob/master/tests/errors/programs/errors/src/lib.rs) in the Anchor repository.
0 commit comments