Skip to content

Commit f8a27c9

Browse files
Merge pull request #210 from metaplex-foundation/feat/execute
Adding execute IX
2 parents 2b8875c + 63831bb commit f8a27c9

File tree

25 files changed

+1907
-4
lines changed

25 files changed

+1907
-4
lines changed

Cargo.lock

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/**
2+
* This code was AUTOGENERATED using the kinobi library.
3+
* Please DO NOT EDIT THIS FILE, instead use visitors
4+
* to add features, then rerun kinobi to update it.
5+
*
6+
* @see https://github.com/metaplex-foundation/kinobi
7+
*/
8+
9+
import {
10+
Account,
11+
Context,
12+
Pda,
13+
PublicKey,
14+
RpcAccount,
15+
RpcGetAccountOptions,
16+
RpcGetAccountsOptions,
17+
assertAccountExists,
18+
deserializeAccount,
19+
gpaBuilder,
20+
publicKey as toPublicKey,
21+
} from '@metaplex-foundation/umi';
22+
import {
23+
Serializer,
24+
bytes,
25+
publicKey as publicKeySerializer,
26+
string,
27+
struct,
28+
} from '@metaplex-foundation/umi/serializers';
29+
30+
export type AssetSigner = Account<AssetSignerAccountData>;
31+
32+
export type AssetSignerAccountData = { data: Uint8Array };
33+
34+
export type AssetSignerAccountDataArgs = AssetSignerAccountData;
35+
36+
export function getAssetSignerAccountDataSerializer(): Serializer<
37+
AssetSignerAccountDataArgs,
38+
AssetSignerAccountData
39+
> {
40+
return struct<AssetSignerAccountData>([['data', bytes()]], {
41+
description: 'AssetSignerAccountData',
42+
}) as Serializer<AssetSignerAccountDataArgs, AssetSignerAccountData>;
43+
}
44+
45+
export function deserializeAssetSigner(rawAccount: RpcAccount): AssetSigner {
46+
return deserializeAccount(rawAccount, getAssetSignerAccountDataSerializer());
47+
}
48+
49+
export async function fetchAssetSigner(
50+
context: Pick<Context, 'rpc'>,
51+
publicKey: PublicKey | Pda,
52+
options?: RpcGetAccountOptions
53+
): Promise<AssetSigner> {
54+
const maybeAccount = await context.rpc.getAccount(
55+
toPublicKey(publicKey, false),
56+
options
57+
);
58+
assertAccountExists(maybeAccount, 'AssetSigner');
59+
return deserializeAssetSigner(maybeAccount);
60+
}
61+
62+
export async function safeFetchAssetSigner(
63+
context: Pick<Context, 'rpc'>,
64+
publicKey: PublicKey | Pda,
65+
options?: RpcGetAccountOptions
66+
): Promise<AssetSigner | null> {
67+
const maybeAccount = await context.rpc.getAccount(
68+
toPublicKey(publicKey, false),
69+
options
70+
);
71+
return maybeAccount.exists ? deserializeAssetSigner(maybeAccount) : null;
72+
}
73+
74+
export async function fetchAllAssetSigner(
75+
context: Pick<Context, 'rpc'>,
76+
publicKeys: Array<PublicKey | Pda>,
77+
options?: RpcGetAccountsOptions
78+
): Promise<AssetSigner[]> {
79+
const maybeAccounts = await context.rpc.getAccounts(
80+
publicKeys.map((key) => toPublicKey(key, false)),
81+
options
82+
);
83+
return maybeAccounts.map((maybeAccount) => {
84+
assertAccountExists(maybeAccount, 'AssetSigner');
85+
return deserializeAssetSigner(maybeAccount);
86+
});
87+
}
88+
89+
export async function safeFetchAllAssetSigner(
90+
context: Pick<Context, 'rpc'>,
91+
publicKeys: Array<PublicKey | Pda>,
92+
options?: RpcGetAccountsOptions
93+
): Promise<AssetSigner[]> {
94+
const maybeAccounts = await context.rpc.getAccounts(
95+
publicKeys.map((key) => toPublicKey(key, false)),
96+
options
97+
);
98+
return maybeAccounts
99+
.filter((maybeAccount) => maybeAccount.exists)
100+
.map((maybeAccount) => deserializeAssetSigner(maybeAccount as RpcAccount));
101+
}
102+
103+
export function getAssetSignerGpaBuilder(
104+
context: Pick<Context, 'rpc' | 'programs'>
105+
) {
106+
const programId = context.programs.getPublicKey(
107+
'mplCore',
108+
'CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d'
109+
);
110+
return gpaBuilder(context, programId)
111+
.registerFields<{ data: Uint8Array }>({ data: [0, bytes()] })
112+
.deserializeUsing<AssetSigner>((account) =>
113+
deserializeAssetSigner(account)
114+
);
115+
}
116+
117+
export function getAssetSignerSize(): number {
118+
return 0;
119+
}
120+
121+
export function findAssetSignerPda(
122+
context: Pick<Context, 'eddsa' | 'programs'>,
123+
seeds: {
124+
/** The address of the asset account */
125+
asset: PublicKey;
126+
}
127+
): Pda {
128+
const programId = context.programs.getPublicKey(
129+
'mplCore',
130+
'CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d'
131+
);
132+
return context.eddsa.findPda(programId, [
133+
string({ size: 'variable' }).serialize('mpl-core-execute'),
134+
publicKeySerializer().serialize(seeds.asset),
135+
]);
136+
}
137+
138+
export async function fetchAssetSignerFromSeeds(
139+
context: Pick<Context, 'eddsa' | 'programs' | 'rpc'>,
140+
seeds: Parameters<typeof findAssetSignerPda>[1],
141+
options?: RpcGetAccountOptions
142+
): Promise<AssetSigner> {
143+
return fetchAssetSigner(context, findAssetSignerPda(context, seeds), options);
144+
}
145+
146+
export async function safeFetchAssetSignerFromSeeds(
147+
context: Pick<Context, 'eddsa' | 'programs' | 'rpc'>,
148+
seeds: Parameters<typeof findAssetSignerPda>[1],
149+
options?: RpcGetAccountOptions
150+
): Promise<AssetSigner | null> {
151+
return safeFetchAssetSigner(
152+
context,
153+
findAssetSignerPda(context, seeds),
154+
options
155+
);
156+
}

clients/js/src/generated/accounts/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* @see https://github.com/metaplex-foundation/kinobi
77
*/
88

9+
export * from './assetSigner';
910
export * from './assetV1';
1011
export * from './collectionV1';
1112
export * from './hashedAssetV1';

clients/js/src/generated/errors/mplCore.ts

+17
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,23 @@ nameToErrorMap.set(
709709
PermanentDelegatesPreventMoveError
710710
);
711711

712+
/** InvalidExecutePda: Invalid Signing PDA for Asset or Collection Execute */
713+
export class InvalidExecutePdaError extends ProgramError {
714+
override readonly name: string = 'InvalidExecutePda';
715+
716+
readonly code: number = 0x31; // 49
717+
718+
constructor(program: Program, cause?: Error) {
719+
super(
720+
'Invalid Signing PDA for Asset or Collection Execute',
721+
program,
722+
cause
723+
);
724+
}
725+
}
726+
codeToErrorMap.set(0x31, InvalidExecutePdaError);
727+
nameToErrorMap.set('InvalidExecutePda', InvalidExecutePdaError);
728+
712729
/**
713730
* Attempts to resolve a custom program error from the provided error code.
714731
* @category Errors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/**
2+
* This code was AUTOGENERATED using the kinobi library.
3+
* Please DO NOT EDIT THIS FILE, instead use visitors
4+
* to add features, then rerun kinobi to update it.
5+
*
6+
* @see https://github.com/metaplex-foundation/kinobi
7+
*/
8+
9+
import {
10+
Context,
11+
Pda,
12+
PublicKey,
13+
Signer,
14+
TransactionBuilder,
15+
transactionBuilder,
16+
} from '@metaplex-foundation/umi';
17+
import {
18+
Serializer,
19+
bytes,
20+
mapSerializer,
21+
struct,
22+
u32,
23+
u8,
24+
} from '@metaplex-foundation/umi/serializers';
25+
import { findAssetSignerPda } from '../accounts';
26+
import {
27+
ResolvedAccount,
28+
ResolvedAccountsWithIndices,
29+
expectPublicKey,
30+
getAccountMetasAndSigners,
31+
} from '../shared';
32+
33+
// Accounts.
34+
export type ExecuteV1InstructionAccounts = {
35+
/** The address of the asset */
36+
asset: PublicKey | Pda;
37+
/** The collection to which the asset belongs */
38+
collection?: PublicKey | Pda;
39+
/** The signing PDA for the asset */
40+
assetSigner?: PublicKey | Pda;
41+
/** The account paying for the storage fees */
42+
payer?: Signer;
43+
/** The owner or delegate of the asset */
44+
authority?: Signer;
45+
/** The system program */
46+
systemProgram?: PublicKey | Pda;
47+
/** The program id of the instruction */
48+
programId?: PublicKey | Pda;
49+
};
50+
51+
// Data.
52+
export type ExecuteV1InstructionData = {
53+
discriminator: number;
54+
instructionData: Uint8Array;
55+
};
56+
57+
export type ExecuteV1InstructionDataArgs = { instructionData: Uint8Array };
58+
59+
export function getExecuteV1InstructionDataSerializer(): Serializer<
60+
ExecuteV1InstructionDataArgs,
61+
ExecuteV1InstructionData
62+
> {
63+
return mapSerializer<
64+
ExecuteV1InstructionDataArgs,
65+
any,
66+
ExecuteV1InstructionData
67+
>(
68+
struct<ExecuteV1InstructionData>(
69+
[
70+
['discriminator', u8()],
71+
['instructionData', bytes({ size: u32() })],
72+
],
73+
{ description: 'ExecuteV1InstructionData' }
74+
),
75+
(value) => ({ ...value, discriminator: 31 })
76+
) as Serializer<ExecuteV1InstructionDataArgs, ExecuteV1InstructionData>;
77+
}
78+
79+
// Args.
80+
export type ExecuteV1InstructionArgs = ExecuteV1InstructionDataArgs;
81+
82+
// Instruction.
83+
export function executeV1(
84+
context: Pick<Context, 'eddsa' | 'payer' | 'programs'>,
85+
input: ExecuteV1InstructionAccounts & ExecuteV1InstructionArgs
86+
): TransactionBuilder {
87+
// Program ID.
88+
const programId = context.programs.getPublicKey(
89+
'mplCore',
90+
'CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d'
91+
);
92+
93+
// Accounts.
94+
const resolvedAccounts = {
95+
asset: {
96+
index: 0,
97+
isWritable: true as boolean,
98+
value: input.asset ?? null,
99+
},
100+
collection: {
101+
index: 1,
102+
isWritable: true as boolean,
103+
value: input.collection ?? null,
104+
},
105+
assetSigner: {
106+
index: 2,
107+
isWritable: false as boolean,
108+
value: input.assetSigner ?? null,
109+
},
110+
payer: {
111+
index: 3,
112+
isWritable: true as boolean,
113+
value: input.payer ?? null,
114+
},
115+
authority: {
116+
index: 4,
117+
isWritable: false as boolean,
118+
value: input.authority ?? null,
119+
},
120+
systemProgram: {
121+
index: 5,
122+
isWritable: false as boolean,
123+
value: input.systemProgram ?? null,
124+
},
125+
programId: {
126+
index: 6,
127+
isWritable: false as boolean,
128+
value: input.programId ?? null,
129+
},
130+
} satisfies ResolvedAccountsWithIndices;
131+
132+
// Arguments.
133+
const resolvedArgs: ExecuteV1InstructionArgs = { ...input };
134+
135+
// Default values.
136+
if (!resolvedAccounts.assetSigner.value) {
137+
resolvedAccounts.assetSigner.value = findAssetSignerPda(context, {
138+
asset: expectPublicKey(resolvedAccounts.asset.value),
139+
});
140+
}
141+
if (!resolvedAccounts.payer.value) {
142+
resolvedAccounts.payer.value = context.payer;
143+
}
144+
if (!resolvedAccounts.systemProgram.value) {
145+
resolvedAccounts.systemProgram.value = context.programs.getPublicKey(
146+
'splSystem',
147+
'11111111111111111111111111111111'
148+
);
149+
resolvedAccounts.systemProgram.isWritable = false;
150+
}
151+
if (!resolvedAccounts.programId.value) {
152+
resolvedAccounts.programId.value = programId;
153+
resolvedAccounts.programId.isWritable = false;
154+
}
155+
156+
// Accounts in order.
157+
const orderedAccounts: ResolvedAccount[] = Object.values(
158+
resolvedAccounts
159+
).sort((a, b) => a.index - b.index);
160+
161+
// Keys and Signers.
162+
const [keys, signers] = getAccountMetasAndSigners(
163+
orderedAccounts,
164+
'programId',
165+
programId
166+
);
167+
168+
// Data.
169+
const data = getExecuteV1InstructionDataSerializer().serialize(
170+
resolvedArgs as ExecuteV1InstructionDataArgs
171+
);
172+
173+
// Bytes Created On Chain.
174+
const bytesCreatedOnChain = 0;
175+
176+
return transactionBuilder([
177+
{ instruction: { keys, programId, data }, signers, bytesCreatedOnChain },
178+
]);
179+
}

0 commit comments

Comments
 (0)