@codama/renderers-rust 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +48 -0
- package/dist/index.node.cjs +909 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.mjs +900 -0
- package/dist/index.node.mjs.map +1 -0
- package/dist/templates/accountsMod.njk +13 -0
- package/dist/templates/accountsPage.njk +160 -0
- package/dist/templates/definedTypesMod.njk +13 -0
- package/dist/templates/definedTypesPage.njk +15 -0
- package/dist/templates/errorsMod.njk +17 -0
- package/dist/templates/errorsPage.njk +23 -0
- package/dist/templates/instructionsCpiPage.njk +185 -0
- package/dist/templates/instructionsCpiPageBuilder.njk +145 -0
- package/dist/templates/instructionsMod.njk +13 -0
- package/dist/templates/instructionsPage.njk +159 -0
- package/dist/templates/instructionsPageBuilder.njk +128 -0
- package/dist/templates/layout.njk +7 -0
- package/dist/templates/macros.njk +6 -0
- package/dist/templates/programsMod.njk +13 -0
- package/dist/templates/rootMod.njk +26 -0
- package/dist/templates/sharedPage.njk +93 -0
- package/dist/types/ImportMap.d.ts +16 -0
- package/dist/types/ImportMap.d.ts.map +1 -0
- package/dist/types/getRenderMapVisitor.d.ts +9 -0
- package/dist/types/getRenderMapVisitor.d.ts.map +1 -0
- package/dist/types/getTypeManifestVisitor.d.ts +13 -0
- package/dist/types/getTypeManifestVisitor.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/renderValueNodeVisitor.d.ts +13 -0
- package/dist/types/renderValueNodeVisitor.d.ts.map +1 -0
- package/dist/types/renderVisitor.d.ts +9 -0
- package/dist/types/renderVisitor.d.ts.map +1 -0
- package/dist/types/utils/codecs.d.ts +3 -0
- package/dist/types/utils/codecs.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +4 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/linkOverrides.d.ts +14 -0
- package/dist/types/utils/linkOverrides.d.ts.map +1 -0
- package/dist/types/utils/render.d.ts +4 -0
- package/dist/types/utils/render.d.ts.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/// Instruction builder for `{{ instruction.name | pascalCase }}` via CPI.
|
|
2
|
+
///
|
|
3
|
+
/// ### Accounts:
|
|
4
|
+
///
|
|
5
|
+
{% for account in instruction.accounts %}
|
|
6
|
+
{% set modifiers = '' %}
|
|
7
|
+
{% if account.isWritable %}
|
|
8
|
+
{% set modifiers = 'writable' %}
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if account.isSigner %}
|
|
11
|
+
{% set modifiers = modifiers + ', signer' if modifiers.length > 0 else 'signer' %}
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% if account.isOptional %}
|
|
14
|
+
{% set modifiers = modifiers + ', optional' if modifiers.length > 0 else 'optional' %}
|
|
15
|
+
{% endif %}
|
|
16
|
+
{{ '/// ' + loop.index0 + '. `[' + modifiers + ']` ' + account.name | snakeCase }}
|
|
17
|
+
{% endfor %}
|
|
18
|
+
#[derive(Clone, Debug)]
|
|
19
|
+
pub struct {{ instruction.name | pascalCase }}CpiBuilder<'a, 'b> {
|
|
20
|
+
instruction: Box<{{ instruction.name | pascalCase }}CpiBuilderInstruction<'a, 'b>>,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
impl<'a, 'b> {{ instruction.name | pascalCase }}CpiBuilder<'a, 'b> {
|
|
24
|
+
pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
|
|
25
|
+
let instruction = Box::new({{ instruction.name | pascalCase }}CpiBuilderInstruction {
|
|
26
|
+
__program: program,
|
|
27
|
+
{% for account in instruction.accounts %}
|
|
28
|
+
{{ account.name | snakeCase }}: None,
|
|
29
|
+
{% endfor %}
|
|
30
|
+
{% for arg in instructionArgs %}
|
|
31
|
+
{% if not arg.default %}
|
|
32
|
+
{{ arg.name | snakeCase }}: None,
|
|
33
|
+
{% endif %}
|
|
34
|
+
{% endfor %}
|
|
35
|
+
__remaining_accounts: Vec::new(),
|
|
36
|
+
});
|
|
37
|
+
Self { instruction }
|
|
38
|
+
}
|
|
39
|
+
{% for account in instruction.accounts %}
|
|
40
|
+
{{'/// `[optional account]`\n' if account.isOptional }}
|
|
41
|
+
{{- macros.docblock(account.docs) -}}
|
|
42
|
+
#[inline(always)]
|
|
43
|
+
pub fn {{ account.name | snakeCase }}(&mut self, {{ account.name | snakeCase }}: {{ "Option<&'b solana_program::account_info::AccountInfo<'a>>" if account.isOptional else "&'b solana_program::account_info::AccountInfo<'a>" }}{{ ', as_signer: bool' if account.isSigner === 'either' }}) -> &mut Self {
|
|
44
|
+
{% if account.isOptional %}
|
|
45
|
+
{% if account.isSigner === 'either' %}
|
|
46
|
+
if let Some({{ account.name | snakeCase }}) = {{ account.name | snakeCase }} {
|
|
47
|
+
self.instruction.{{ account.name | snakeCase }} = Some(({{ account.name | snakeCase }}, as_signer));
|
|
48
|
+
} else {
|
|
49
|
+
self.instruction.{{ account.name | snakeCase }} = None;
|
|
50
|
+
}
|
|
51
|
+
{% else %}
|
|
52
|
+
self.instruction.{{ account.name | snakeCase }} = {{ account.name | snakeCase }};
|
|
53
|
+
{% endif %}
|
|
54
|
+
{% else %}
|
|
55
|
+
{% if account.isSigner === 'either' %}
|
|
56
|
+
self.instruction.{{ account.name | snakeCase }} = Some(({{ account.name | snakeCase }}, as_signer));
|
|
57
|
+
{% else %}
|
|
58
|
+
self.instruction.{{ account.name | snakeCase }} = Some({{ account.name | snakeCase }});
|
|
59
|
+
{% endif %}
|
|
60
|
+
{% endif %}
|
|
61
|
+
self
|
|
62
|
+
}
|
|
63
|
+
{% endfor %}
|
|
64
|
+
{% for arg in instructionArgs %}
|
|
65
|
+
{% if not arg.default %}
|
|
66
|
+
{{'/// `[optional argument]`\n' if arg.innerOptionType }}
|
|
67
|
+
{{- "/// `[optional argument, defaults to '" + arg.value + "']`\n" if not arg.innerOptionType and arg.value -}}
|
|
68
|
+
{{- macros.docblock(arg.docs) -}}
|
|
69
|
+
#[inline(always)]
|
|
70
|
+
pub fn {{ arg.name | snakeCase }}(&mut self, {{ arg.name | snakeCase }}: {{ arg.innerOptionType or arg.type }}) -> &mut Self {
|
|
71
|
+
self.instruction.{{ arg.name | snakeCase }} = Some({{ arg.name | snakeCase }});
|
|
72
|
+
self
|
|
73
|
+
}
|
|
74
|
+
{% endif %}
|
|
75
|
+
{% endfor %}
|
|
76
|
+
/// Add an additional account to the instruction.
|
|
77
|
+
#[inline(always)]
|
|
78
|
+
pub fn add_remaining_account(&mut self, account: &'b solana_program::account_info::AccountInfo<'a>, is_writable: bool, is_signer: bool) -> &mut Self {
|
|
79
|
+
self.instruction.__remaining_accounts.push((account, is_writable, is_signer));
|
|
80
|
+
self
|
|
81
|
+
}
|
|
82
|
+
/// Add additional accounts to the instruction.
|
|
83
|
+
///
|
|
84
|
+
/// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not,
|
|
85
|
+
/// and a `bool` indicating whether the account is a signer or not.
|
|
86
|
+
#[inline(always)]
|
|
87
|
+
pub fn add_remaining_accounts(&mut self, accounts: &[(&'b solana_program::account_info::AccountInfo<'a>, bool, bool)]) -> &mut Self {
|
|
88
|
+
self.instruction.__remaining_accounts.extend_from_slice(accounts);
|
|
89
|
+
self
|
|
90
|
+
}
|
|
91
|
+
#[inline(always)]
|
|
92
|
+
pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
|
|
93
|
+
self.invoke_signed(&[])
|
|
94
|
+
}
|
|
95
|
+
#[allow(clippy::clone_on_copy)]
|
|
96
|
+
#[allow(clippy::vec_init_then_push)]
|
|
97
|
+
pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program::entrypoint::ProgramResult {
|
|
98
|
+
{% if hasArgs %}
|
|
99
|
+
let args = {{ instruction.name | pascalCase }}InstructionArgs {
|
|
100
|
+
{% for arg in instructionArgs %}
|
|
101
|
+
{% if not arg.default %}
|
|
102
|
+
{% if arg.optional %}
|
|
103
|
+
{% if arg.innerOptionType %}
|
|
104
|
+
{{ arg.name | snakeCase }}: self.instruction.{{ arg.name | snakeCase }}.clone(),
|
|
105
|
+
{% else %}
|
|
106
|
+
{{ arg.name | snakeCase }}: self.instruction.{{ arg.name | snakeCase }}.clone(){{ '.unwrap_or(' + arg.value + ')' if arg.value else '.expect(\"' + arg.name | snakeCase + ' is not set\")' }},
|
|
107
|
+
{% endif %}
|
|
108
|
+
{% else %}
|
|
109
|
+
{{ arg.name | snakeCase }}: self.instruction.{{ arg.name | snakeCase }}.clone(){{ '.expect(\"' + arg.name | snakeCase + ' is not set\")' if not arg.innerOptionType }},
|
|
110
|
+
{% endif %}
|
|
111
|
+
{% endif %}
|
|
112
|
+
{% endfor %}
|
|
113
|
+
};
|
|
114
|
+
{% endif %}
|
|
115
|
+
let instruction = {{ instruction.name | pascalCase }}Cpi {
|
|
116
|
+
__program: self.instruction.__program,
|
|
117
|
+
{% for account in instruction.accounts %}
|
|
118
|
+
{{ account.name | snakeCase }}: self.instruction.{{ account.name | snakeCase }}{{ '.expect(\"' + account.name | snakeCase + ' is not set\")' if not account.isOptional }},
|
|
119
|
+
{% endfor %}
|
|
120
|
+
{% if hasArgs %}
|
|
121
|
+
__args: args,
|
|
122
|
+
{% endif %}
|
|
123
|
+
};
|
|
124
|
+
instruction.invoke_signed_with_remaining_accounts(signers_seeds, &self.instruction.__remaining_accounts)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#[derive(Clone, Debug)]
|
|
129
|
+
struct {{ instruction.name | pascalCase }}CpiBuilderInstruction<'a, 'b> {
|
|
130
|
+
__program: &'b solana_program::account_info::AccountInfo<'a>,
|
|
131
|
+
{% for account in instruction.accounts %}
|
|
132
|
+
{% if account.isSigner === 'either' %}
|
|
133
|
+
{{ account.name | snakeCase }}: Option<(&'b solana_program::account_info::AccountInfo<'a>, bool)>,
|
|
134
|
+
{% else %}
|
|
135
|
+
{{ account.name | snakeCase }}: Option<&'b solana_program::account_info::AccountInfo<'a>>,
|
|
136
|
+
{% endif %}
|
|
137
|
+
{% endfor %}
|
|
138
|
+
{% for arg in instructionArgs %}
|
|
139
|
+
{% if not arg.default %}
|
|
140
|
+
{{ arg.name | snakeCase }}: {{ arg.type if arg.innerOptionType else 'Option<' + arg.type + '>' }},
|
|
141
|
+
{% endif %}
|
|
142
|
+
{% endfor %}
|
|
143
|
+
/// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`.
|
|
144
|
+
__remaining_accounts: Vec<(&'b solana_program::account_info::AccountInfo<'a>, bool, bool)>,
|
|
145
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{% extends "layout.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block main %}
|
|
4
|
+
|
|
5
|
+
{% for instruction in instructionsToExport | sort(false, false, 'name') %}
|
|
6
|
+
pub(crate) mod r#{{ instruction.name | snakeCase }};
|
|
7
|
+
{% endfor %}
|
|
8
|
+
|
|
9
|
+
{% for instruction in instructionsToExport | sort(false, false, 'name') %}
|
|
10
|
+
pub use self::r#{{ instruction.name | snakeCase }}::*;
|
|
11
|
+
{% endfor %}
|
|
12
|
+
|
|
13
|
+
{% endblock %}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
{% extends "layout.njk" %}
|
|
2
|
+
{% import "macros.njk" as macros %}
|
|
3
|
+
|
|
4
|
+
{% block main %}
|
|
5
|
+
|
|
6
|
+
{{ imports }}
|
|
7
|
+
|
|
8
|
+
/// Accounts.
|
|
9
|
+
pub struct {{ instruction.name | pascalCase }} {
|
|
10
|
+
{% for account in instruction.accounts %}
|
|
11
|
+
{% if account.docs.length > 0 %}
|
|
12
|
+
{{ macros.docblock(account.docs) }}
|
|
13
|
+
{% endif %}
|
|
14
|
+
|
|
15
|
+
{% if account.isSigner === 'either' %}
|
|
16
|
+
{% set type = '(solana_program::pubkey::Pubkey, bool)' %}
|
|
17
|
+
{% else %}
|
|
18
|
+
{% set type = 'solana_program::pubkey::Pubkey' %}
|
|
19
|
+
{% endif %}
|
|
20
|
+
|
|
21
|
+
{% if account.isOptional %}
|
|
22
|
+
pub {{ account.name | snakeCase }}: Option<{{ type }}>,
|
|
23
|
+
{% else %}
|
|
24
|
+
pub {{ account.name | snakeCase }}: {{ type }},
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
impl {{ instruction.name | pascalCase }} {
|
|
30
|
+
pub fn instruction(&self{{ ', args: ' + instruction.name | pascalCase + 'InstructionArgs' if hasArgs }}) -> solana_program::instruction::Instruction {
|
|
31
|
+
self.instruction_with_remaining_accounts({{ 'args, ' if hasArgs }}&[])
|
|
32
|
+
}
|
|
33
|
+
#[allow(clippy::vec_init_then_push)]
|
|
34
|
+
pub fn instruction_with_remaining_accounts(&self{{ ', args: ' + instruction.name | pascalCase + 'InstructionArgs' if hasArgs }}, remaining_accounts: &[solana_program::instruction::AccountMeta]) -> solana_program::instruction::Instruction {
|
|
35
|
+
let mut accounts = Vec::with_capacity({{ instruction.accounts.length }} + remaining_accounts.len());
|
|
36
|
+
{% for account in instruction.accounts %}
|
|
37
|
+
{% if account.isSigner === 'either' %}
|
|
38
|
+
{% if account.isOptional %}
|
|
39
|
+
{% if instruction.optionalAccountStrategy === 'programId' %}
|
|
40
|
+
if let Some(({{ account.name | snakeCase }}, signer)) = self.{{ account.name | snakeCase }} {
|
|
41
|
+
accounts.push(solana_program::instruction::AccountMeta::{{ 'new' if account.isWritable else 'new_readonly' }}(
|
|
42
|
+
{{ account.name | snakeCase }},
|
|
43
|
+
signer,
|
|
44
|
+
));
|
|
45
|
+
} else {
|
|
46
|
+
accounts.push(solana_program::instruction::AccountMeta::new_readonly(
|
|
47
|
+
crate::{{ program.name | snakeCase | upper }}_ID,
|
|
48
|
+
false,
|
|
49
|
+
));
|
|
50
|
+
}
|
|
51
|
+
{% else %}
|
|
52
|
+
if let Some(({{ account.name | snakeCase }}, signer)) = self.{{ account.name | snakeCase }} {
|
|
53
|
+
accounts.push(solana_program::instruction::AccountMeta::{{ 'new' if account.isWritable else 'new_readonly' }}(
|
|
54
|
+
{{ account.name | snakeCase }},
|
|
55
|
+
signer,
|
|
56
|
+
));
|
|
57
|
+
}
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% else %}
|
|
60
|
+
accounts.push(solana_program::instruction::AccountMeta::{{ 'new' if account.isWritable else 'new_readonly' }}(
|
|
61
|
+
self.{{ account.name | snakeCase }}.0,
|
|
62
|
+
self.{{ account.name | snakeCase }}.1,
|
|
63
|
+
));
|
|
64
|
+
{% endif %}
|
|
65
|
+
{% else %}
|
|
66
|
+
{% if account.isOptional %}
|
|
67
|
+
{% if instruction.optionalAccountStrategy === 'programId' %}
|
|
68
|
+
if let Some({{ account.name | snakeCase }}) = self.{{ account.name | snakeCase }} {
|
|
69
|
+
accounts.push(solana_program::instruction::AccountMeta::{{ 'new' if account.isWritable else 'new_readonly' }}(
|
|
70
|
+
{{ account.name | snakeCase }},
|
|
71
|
+
{{ 'true' if account.isSigner else 'false' }},
|
|
72
|
+
));
|
|
73
|
+
} else {
|
|
74
|
+
accounts.push(solana_program::instruction::AccountMeta::new_readonly(
|
|
75
|
+
crate::{{ program.name | snakeCase | upper }}_ID,
|
|
76
|
+
false,
|
|
77
|
+
));
|
|
78
|
+
}
|
|
79
|
+
{% elif account.isOptional %}
|
|
80
|
+
if let Some({{ account.name | snakeCase }}) = self.{{ account.name | snakeCase }} {
|
|
81
|
+
accounts.push(solana_program::instruction::AccountMeta::{{ 'new' if account.isWritable else 'new_readonly' }}(
|
|
82
|
+
{{ account.name | snakeCase }},
|
|
83
|
+
{{ 'true' if account.isSigner else 'false' }},
|
|
84
|
+
));
|
|
85
|
+
}
|
|
86
|
+
{% endif %}
|
|
87
|
+
{% else %}
|
|
88
|
+
accounts.push(solana_program::instruction::AccountMeta::{{ 'new' if account.isWritable else 'new_readonly' }}(
|
|
89
|
+
self.{{ account.name | snakeCase }},
|
|
90
|
+
{{ 'true' if account.isSigner else 'false' }}
|
|
91
|
+
));
|
|
92
|
+
{% endif %}
|
|
93
|
+
{% endif %}
|
|
94
|
+
{% endfor %}
|
|
95
|
+
accounts.extend_from_slice(remaining_accounts);
|
|
96
|
+
let {{ 'mut ' if hasArgs }}data = {{ instruction.name | pascalCase }}InstructionData::new().try_to_vec().unwrap();
|
|
97
|
+
{% if hasArgs %}
|
|
98
|
+
let mut args = args.try_to_vec().unwrap();
|
|
99
|
+
data.append(&mut args);
|
|
100
|
+
{% endif %}
|
|
101
|
+
|
|
102
|
+
solana_program::instruction::Instruction {
|
|
103
|
+
program_id: crate::{{ program.name | snakeCase | upper }}_ID,
|
|
104
|
+
accounts,
|
|
105
|
+
data,
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
#[derive(BorshDeserialize, BorshSerialize)]
|
|
111
|
+
pub struct {{ instruction.name | pascalCase }}InstructionData {
|
|
112
|
+
{% for arg in instructionArgs %}
|
|
113
|
+
{% if arg.default %}
|
|
114
|
+
{{ arg.name | snakeCase }}: {{ arg.type }},
|
|
115
|
+
{% endif %}
|
|
116
|
+
{% endfor %}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
impl {{ instruction.name | pascalCase }}InstructionData {
|
|
120
|
+
pub fn new() -> Self {
|
|
121
|
+
Self {
|
|
122
|
+
{% for arg in instructionArgs %}
|
|
123
|
+
{% if arg.default %}
|
|
124
|
+
{{ arg.name | snakeCase }}: {{ arg.value }},
|
|
125
|
+
{% endif %}
|
|
126
|
+
{% endfor %}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
impl Default for {{ instruction.name | pascalCase }}InstructionData {
|
|
132
|
+
fn default() -> Self {
|
|
133
|
+
Self::new()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
{% if hasArgs %}
|
|
138
|
+
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
|
|
139
|
+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
|
140
|
+
pub struct {{ instruction.name | pascalCase }}InstructionArgs {
|
|
141
|
+
{% for arg in instructionArgs %}
|
|
142
|
+
{% if not arg.default %}
|
|
143
|
+
pub {{ arg.name | snakeCase }}: {{ arg.type }},
|
|
144
|
+
{% endif %}
|
|
145
|
+
{% endfor %}
|
|
146
|
+
}
|
|
147
|
+
{% endif %}
|
|
148
|
+
|
|
149
|
+
{% for nestedStruct in typeManifest.nestedStructs %}
|
|
150
|
+
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
|
|
151
|
+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
|
152
|
+
{{ nestedStruct }}
|
|
153
|
+
{% endfor %}
|
|
154
|
+
|
|
155
|
+
{% include "instructionsPageBuilder.njk" %}
|
|
156
|
+
|
|
157
|
+
{% include "instructionsCpiPage.njk" %}
|
|
158
|
+
|
|
159
|
+
{% endblock %}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/// Instruction builder for `{{ instruction.name | pascalCase }}`.
|
|
2
|
+
///
|
|
3
|
+
/// ### Accounts:
|
|
4
|
+
///
|
|
5
|
+
{% for account in instruction.accounts %}
|
|
6
|
+
{% set modifiers = '' %}
|
|
7
|
+
{% if account.isWritable %}
|
|
8
|
+
{% set modifiers = 'writable' %}
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if account.isSigner %}
|
|
11
|
+
{% set modifiers = modifiers + ', signer' if modifiers.length > 0 else 'signer' %}
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% if account.isOptional or account.defaultValue.kind === 'publicKeyValueNode' %}
|
|
14
|
+
{% set modifiers = modifiers + ', optional' if modifiers.length > 0 else 'optional' %}
|
|
15
|
+
{% endif %}
|
|
16
|
+
{{ '/// ' + loop.index0 + '. `[' + modifiers + ']` ' + account.name | snakeCase }}
|
|
17
|
+
{{- " (default to `" + account.defaultValue.publicKey + "`)" if account.defaultValue.kind === 'publicKeyValueNode' }}
|
|
18
|
+
{% endfor %}
|
|
19
|
+
#[derive(Clone, Debug, Default)]
|
|
20
|
+
pub struct {{ instruction.name | pascalCase }}Builder {
|
|
21
|
+
{% for account in instruction.accounts %}
|
|
22
|
+
{% if account.isSigner === 'either' %}
|
|
23
|
+
{{ account.name | snakeCase }}: Option<(solana_program::pubkey::Pubkey, bool)>,
|
|
24
|
+
{% else %}
|
|
25
|
+
{{ account.name | snakeCase }}: Option<solana_program::pubkey::Pubkey>,
|
|
26
|
+
{% endif %}
|
|
27
|
+
{% endfor %}
|
|
28
|
+
{% for arg in instructionArgs %}
|
|
29
|
+
{% if not arg.default %}
|
|
30
|
+
{{ arg.name | snakeCase }}: {{ arg.type if arg.innerOptionType else 'Option<' + arg.type + '>' }},
|
|
31
|
+
{% endif %}
|
|
32
|
+
{% endfor %}
|
|
33
|
+
__remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
impl {{ instruction.name | pascalCase }}Builder {
|
|
37
|
+
pub fn new() -> Self {
|
|
38
|
+
Self::default()
|
|
39
|
+
}
|
|
40
|
+
{% for account in instruction.accounts %}
|
|
41
|
+
{% if account.isOptional %}
|
|
42
|
+
{{ '/// `[optional account]`\n' -}}
|
|
43
|
+
{% else %}
|
|
44
|
+
{{ "/// `[optional account, default to '" + account.defaultValue.publicKey + "']`\n" if account.defaultValue.kind === 'publicKeyValueNode' -}}
|
|
45
|
+
{% endif %}
|
|
46
|
+
{{- macros.docblock(account.docs) -}}
|
|
47
|
+
#[inline(always)]
|
|
48
|
+
pub fn {{ account.name | snakeCase }}(&mut self, {{ account.name | snakeCase }}: {{ 'Option<solana_program::pubkey::Pubkey>' if account.isOptional else 'solana_program::pubkey::Pubkey' }}{{ ', as_signer: bool' if account.isSigner === 'either' }}) -> &mut Self {
|
|
49
|
+
{% if account.isOptional %}
|
|
50
|
+
{% if account.isSigner === 'either' %}
|
|
51
|
+
if let Some({{ account.name | snakeCase }}) = {{ account.name | snakeCase }} {
|
|
52
|
+
self.{{ account.name | snakeCase }} = Some(({{ account.name | snakeCase }}, as_signer));
|
|
53
|
+
} else {
|
|
54
|
+
self.{{ account.name | snakeCase }} = None;
|
|
55
|
+
}
|
|
56
|
+
{% else %}
|
|
57
|
+
self.{{ account.name | snakeCase }} = {{ account.name | snakeCase }};
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% else %}
|
|
60
|
+
{% if account.isSigner === 'either' %}
|
|
61
|
+
self.{{ account.name | snakeCase }} = Some(({{ account.name | snakeCase }}, as_signer));
|
|
62
|
+
{% else %}
|
|
63
|
+
self.{{ account.name | snakeCase }} = Some({{ account.name | snakeCase }});
|
|
64
|
+
{% endif %}
|
|
65
|
+
{% endif %}
|
|
66
|
+
self
|
|
67
|
+
}
|
|
68
|
+
{% endfor %}
|
|
69
|
+
{% for arg in instructionArgs %}
|
|
70
|
+
{% if not arg.default %}
|
|
71
|
+
{{ '/// `[optional argument]`\n' if arg.innerOptionType }}
|
|
72
|
+
{{- "/// `[optional argument, defaults to '" + arg.value + "']`\n" if not arg.innerOptionType and arg.value -}}
|
|
73
|
+
{{- macros.docblock(arg.docs) -}}
|
|
74
|
+
#[inline(always)]
|
|
75
|
+
pub fn {{ arg.name | snakeCase }}(&mut self, {{ arg.name | snakeCase }}: {{ arg.innerOptionType or arg.type }}) -> &mut Self {
|
|
76
|
+
self.{{ arg.name | snakeCase }} = Some({{ arg.name | snakeCase }});
|
|
77
|
+
self
|
|
78
|
+
}
|
|
79
|
+
{% endif %}
|
|
80
|
+
{% endfor %}
|
|
81
|
+
/// Add an additional account to the instruction.
|
|
82
|
+
#[inline(always)]
|
|
83
|
+
pub fn add_remaining_account(&mut self, account: solana_program::instruction::AccountMeta) -> &mut Self {
|
|
84
|
+
self.__remaining_accounts.push(account);
|
|
85
|
+
self
|
|
86
|
+
}
|
|
87
|
+
/// Add additional accounts to the instruction.
|
|
88
|
+
#[inline(always)]
|
|
89
|
+
pub fn add_remaining_accounts(&mut self, accounts: &[solana_program::instruction::AccountMeta]) -> &mut Self {
|
|
90
|
+
self.__remaining_accounts.extend_from_slice(accounts);
|
|
91
|
+
self
|
|
92
|
+
}
|
|
93
|
+
#[allow(clippy::clone_on_copy)]
|
|
94
|
+
pub fn instruction(&self) -> solana_program::instruction::Instruction {
|
|
95
|
+
let accounts = {{ instruction.name | pascalCase }} {
|
|
96
|
+
{% for account in instruction.accounts %}
|
|
97
|
+
{% if account.isOptional %}
|
|
98
|
+
{{ account.name | snakeCase }}: self.{{ account.name | snakeCase }},
|
|
99
|
+
{% elif account.defaultValue.kind === 'programId' %}
|
|
100
|
+
{{ account.name | snakeCase }}: self.{{ account.name | snakeCase }}, {# Program ID set on the instruction creation. #}
|
|
101
|
+
{% elif account.defaultValue.kind === 'publicKeyValueNode' %}
|
|
102
|
+
{{ account.name | snakeCase }}: self.{{ account.name | snakeCase }}.unwrap_or(solana_program::pubkey!("{{ account.defaultValue.publicKey }}")),
|
|
103
|
+
{% else %}
|
|
104
|
+
{{ account.name | snakeCase }}: self.{{ account.name | snakeCase }}.expect("{{ account.name | snakeCase }} is not set"),
|
|
105
|
+
{% endif %}
|
|
106
|
+
{% endfor %}
|
|
107
|
+
};
|
|
108
|
+
{% if hasArgs %}
|
|
109
|
+
let args = {{ instruction.name | pascalCase }}InstructionArgs {
|
|
110
|
+
{% for arg in instructionArgs %}
|
|
111
|
+
{% if not arg.default %}
|
|
112
|
+
{% if arg.optional %}
|
|
113
|
+
{% if arg.innerOptionType %}
|
|
114
|
+
{{ arg.name | snakeCase }}: self.{{ arg.name | snakeCase }}.clone(),
|
|
115
|
+
{% else %}
|
|
116
|
+
{{ arg.name | snakeCase }}: self.{{ arg.name | snakeCase }}.clone(){{ '.unwrap_or(' + arg.value + ')' if arg.value else '.expect(\"' + arg.name | snakeCase + ' is not set\")' }},
|
|
117
|
+
{% endif %}
|
|
118
|
+
{% else %}
|
|
119
|
+
{{ arg.name | snakeCase }}: self.{{ arg.name | snakeCase }}.clone(){{ '.expect(\"' + arg.name | snakeCase + ' is not set\")' if not arg.innerOptionType }},
|
|
120
|
+
{% endif %}
|
|
121
|
+
{% endif %}
|
|
122
|
+
{% endfor %}
|
|
123
|
+
};
|
|
124
|
+
{% endif %}
|
|
125
|
+
|
|
126
|
+
accounts.instruction_with_remaining_accounts({{ 'args, ' if hasArgs }}&self.__remaining_accounts)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{% extends "layout.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block main %}
|
|
4
|
+
|
|
5
|
+
use solana_program::{pubkey, pubkey::Pubkey};
|
|
6
|
+
|
|
7
|
+
{% for program in programsToExport | sort(false, false, 'name') %}
|
|
8
|
+
|
|
9
|
+
/// `{{ program.name | snakeCase }}` program ID.
|
|
10
|
+
pub const {{ program.name | snakeCase | upper }}_ID: Pubkey = pubkey!("{{ program.publicKey }}");
|
|
11
|
+
{% endfor %}
|
|
12
|
+
|
|
13
|
+
{% endblock %}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{% extends "layout.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block main %}
|
|
4
|
+
|
|
5
|
+
{% if hasAnythingToExport %}
|
|
6
|
+
{% if accountsToExport.length > 0 %}
|
|
7
|
+
pub mod accounts;
|
|
8
|
+
{% endif %}
|
|
9
|
+
{% if programsToExport.length > 0 %}
|
|
10
|
+
pub mod errors;
|
|
11
|
+
{% endif %}
|
|
12
|
+
{% if instructionsToExport.length > 0 %}
|
|
13
|
+
pub mod instructions;
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% if programsToExport.length > 0 %}
|
|
16
|
+
pub mod programs;
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% if definedTypesToExport.length > 0 %}
|
|
19
|
+
pub mod types;
|
|
20
|
+
{% endif %}
|
|
21
|
+
{% endif %}
|
|
22
|
+
|
|
23
|
+
{% if programsToExport.length > 0 %}
|
|
24
|
+
pub(crate) use programs::*;
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% endblock %}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{% extends "layout.njk" %}
|
|
2
|
+
{% block main %}
|
|
3
|
+
|
|
4
|
+
use std::fmt::Debug;
|
|
5
|
+
use std::io::Write;
|
|
6
|
+
use std::ops::{Deref, DerefMut};
|
|
7
|
+
|
|
8
|
+
use borsh::maybestd::io::Read;
|
|
9
|
+
use borsh::{BorshDeserialize, BorshSerialize};
|
|
10
|
+
|
|
11
|
+
/// A vector that deserializes from a stream of bytes.
|
|
12
|
+
///
|
|
13
|
+
/// This is useful for deserializing a vector that does not have
|
|
14
|
+
/// a length prefix. In order to determine how many elements to deserialize,
|
|
15
|
+
/// the type of the elements must implement the trait `Sized`.
|
|
16
|
+
pub struct RemainderVec<T: BorshSerialize + BorshDeserialize>(Vec<T>);
|
|
17
|
+
|
|
18
|
+
/// Deferences the inner `Vec` type.
|
|
19
|
+
impl<T> Deref for RemainderVec<T>
|
|
20
|
+
where
|
|
21
|
+
T: BorshSerialize + BorshDeserialize,
|
|
22
|
+
{
|
|
23
|
+
type Target = Vec<T>;
|
|
24
|
+
|
|
25
|
+
fn deref(&self) -> &Self::Target {
|
|
26
|
+
&self.0
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// Deferences the inner `Vec` type as mutable.
|
|
31
|
+
impl<T> DerefMut for RemainderVec<T>
|
|
32
|
+
where
|
|
33
|
+
T: BorshSerialize + BorshDeserialize,
|
|
34
|
+
{
|
|
35
|
+
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
36
|
+
&mut self.0
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// `Debug` implementation for `RemainderVec`.
|
|
41
|
+
///
|
|
42
|
+
/// This implementation simply forwards to the inner `Vec` type.
|
|
43
|
+
impl<T> Debug for RemainderVec<T>
|
|
44
|
+
where
|
|
45
|
+
T: BorshSerialize + BorshDeserialize + Debug,
|
|
46
|
+
{
|
|
47
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
48
|
+
f.write_fmt(format_args!("{:?}", self.0))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
impl<T> BorshDeserialize for RemainderVec<T>
|
|
53
|
+
where
|
|
54
|
+
T: BorshSerialize + BorshDeserialize,
|
|
55
|
+
{
|
|
56
|
+
fn deserialize_reader<R: Read>(reader: &mut R) -> borsh::maybestd::io::Result<Self> {
|
|
57
|
+
let length = std::mem::size_of::<T>();
|
|
58
|
+
// buffer to read the data
|
|
59
|
+
let mut buffer = vec![0u8; length];
|
|
60
|
+
// vec to store the items
|
|
61
|
+
let mut items: Vec<T> = Vec::new();
|
|
62
|
+
|
|
63
|
+
loop {
|
|
64
|
+
match reader.read(&mut buffer)? {
|
|
65
|
+
0 => break,
|
|
66
|
+
n if n == length => items.push(T::deserialize(&mut buffer.as_slice())?),
|
|
67
|
+
e => {
|
|
68
|
+
return Err(borsh::maybestd::io::Error::new(
|
|
69
|
+
borsh::maybestd::io::ErrorKind::InvalidData,
|
|
70
|
+
format!("unexpected number of bytes (read {e}, expected {length})"),
|
|
71
|
+
))
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Ok(Self(items))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
impl<T> BorshSerialize for RemainderVec<T>
|
|
81
|
+
where
|
|
82
|
+
T: BorshSerialize + BorshDeserialize,
|
|
83
|
+
{
|
|
84
|
+
fn serialize<W: Write>(&self, writer: &mut W) -> borsh::maybestd::io::Result<()> {
|
|
85
|
+
// serialize each item without adding a prefix for the length
|
|
86
|
+
for item in self.0.iter() {
|
|
87
|
+
item.serialize(writer)?;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Ok(())
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
{% endblock %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TypeManifest } from './getTypeManifestVisitor';
|
|
2
|
+
export declare class ImportMap {
|
|
3
|
+
protected readonly _imports: Set<string>;
|
|
4
|
+
protected readonly _aliases: Map<string, string>;
|
|
5
|
+
get imports(): Set<string>;
|
|
6
|
+
get aliases(): Map<string, string>;
|
|
7
|
+
add(imports: Set<string> | string[] | string): ImportMap;
|
|
8
|
+
remove(imports: Set<string> | string[] | string): ImportMap;
|
|
9
|
+
mergeWith(...others: ImportMap[]): ImportMap;
|
|
10
|
+
mergeWithManifest(manifest: TypeManifest): ImportMap;
|
|
11
|
+
addAlias(importName: string, alias: string): ImportMap;
|
|
12
|
+
isEmpty(): boolean;
|
|
13
|
+
resolveDependencyMap(dependencies: Record<string, string>): ImportMap;
|
|
14
|
+
toString(dependencies: Record<string, string>): string;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ImportMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImportMap.d.ts","sourceRoot":"","sources":["../../src/ImportMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAaxD,qBAAa,SAAS;IAClB,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAErD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IAE7D,IAAI,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAEzB;IAED,IAAI,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEjC;IAED,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS;IAMxD,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS;IAM3D,SAAS,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS;IAQ5C,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS;IAIpD,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IAKtD,OAAO,IAAI,OAAO;IAIlB,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAcrE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;CASzD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RenderMap } from '@codama/renderers-core';
|
|
2
|
+
import { LinkOverrides } from './utils';
|
|
3
|
+
export type GetRenderMapOptions = {
|
|
4
|
+
dependencyMap?: Record<string, string>;
|
|
5
|
+
linkOverrides?: LinkOverrides;
|
|
6
|
+
renderParentInstructions?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function getRenderMapVisitor(options?: GetRenderMapOptions): import("@codama/visitors-core").Visitor<RenderMap, "accountNode" | "definedTypeNode" | "instructionNode" | "programNode" | "rootNode">;
|
|
9
|
+
//# sourceMappingURL=getRenderMapVisitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRenderMapVisitor.d.ts","sourceRoot":"","sources":["../../src/getRenderMapVisitor.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAanD,OAAO,EAAwB,aAAa,EAAU,MAAM,SAAS,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACtC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,mBAAwB,0IAqPpE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ImportMap } from './ImportMap';
|
|
2
|
+
import { GetImportFromFunction } from './utils';
|
|
3
|
+
export type TypeManifest = {
|
|
4
|
+
imports: ImportMap;
|
|
5
|
+
nestedStructs: string[];
|
|
6
|
+
type: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function getTypeManifestVisitor(options: {
|
|
9
|
+
getImportFrom: GetImportFromFunction;
|
|
10
|
+
nestedStruct?: boolean;
|
|
11
|
+
parentName?: string | null;
|
|
12
|
+
}): import("@codama/visitors-core").Visitor<TypeManifest, "definedTypeLinkNode" | "accountNode" | "definedTypeNode" | "enumEmptyVariantTypeNode" | "enumStructVariantTypeNode" | "enumTupleVariantTypeNode" | "amountTypeNode" | "arrayTypeNode" | "booleanTypeNode" | "bytesTypeNode" | "dateTimeTypeNode" | "enumTypeNode" | "fixedSizeTypeNode" | "hiddenPrefixTypeNode" | "hiddenSuffixTypeNode" | "mapTypeNode" | "numberTypeNode" | "optionTypeNode" | "postOffsetTypeNode" | "preOffsetTypeNode" | "publicKeyTypeNode" | "remainderOptionTypeNode" | "sentinelTypeNode" | "setTypeNode" | "sizePrefixTypeNode" | "solAmountTypeNode" | "stringTypeNode" | "structTypeNode" | "tupleTypeNode" | "zeroableOptionTypeNode" | "structFieldTypeNode">;
|
|
13
|
+
//# sourceMappingURL=getTypeManifestVisitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTypeManifestVisitor.d.ts","sourceRoot":"","sources":["../../src/getTypeManifestVisitor.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAgB,MAAM,SAAS,CAAC;AAE9D,MAAM,MAAM,YAAY,GAAG;IACvB,OAAO,EAAE,SAAS,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC5C,aAAa,EAAE,qBAAqB,CAAC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,utBAwcA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC"}
|