@typesol/cli 0.15.0 → 0.17.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/CHANGELOG.md +107 -0
- package/README.md +11 -7
- package/dist/cli.js +147 -20
- package/dist/clientgen.js +37 -0
- package/dist/compiler/analyze.d.ts +11 -1
- package/dist/compiler/analyze.js +307 -37
- package/dist/compiler/emit/base.d.ts +7 -0
- package/dist/compiler/emit/base.js +62 -2
- package/dist/compiler/emit/borsh.d.ts +13 -0
- package/dist/compiler/emit/borsh.js +232 -0
- package/dist/compiler/emit/calls.js +50 -15
- package/dist/compiler/emit/cpi.d.ts +32 -8
- package/dist/compiler/emit/cpi.js +706 -25
- package/dist/compiler/emit/expressions.d.ts +11 -0
- package/dist/compiler/emit/expressions.js +126 -4
- package/dist/compiler/emit/function.js +45 -12
- package/dist/compiler/emit/program.js +24 -6
- package/dist/compiler/emit/shared.d.ts +12 -0
- package/dist/compiler/emit/shared.js +22 -4
- package/dist/compiler/emit/statements.d.ts +13 -0
- package/dist/compiler/emit/statements.js +141 -7
- package/dist/compiler/emit/storage.d.ts +6 -1
- package/dist/compiler/emit/storage.js +82 -17
- package/dist/compiler/idl.js +61 -18
- package/dist/compiler/model.d.ts +56 -4
- package/dist/compiler/model.js +8 -2
- package/dist/compiler/toolchain.d.ts +2 -0
- package/dist/compiler/toolchain.js +27 -1
- package/dist/onchain.d.ts +30 -0
- package/dist/onchain.js +53 -0
- package/dist/portgen.d.ts +87 -0
- package/dist/portgen.js +367 -0
- package/dist/templates.js +49 -154
- package/dist/testing.d.ts +66 -0
- package/dist/testing.js +337 -0
- package/dist/workspace.js +11 -1
- package/docs/architecture.md +3 -0
- package/docs/cli.md +16 -2
- package/docs/errors.md +3 -2
- package/docs/language.md +19 -14
- package/docs/mainnet.md +5 -4
- package/docs/migrate-from-anchor.md +113 -0
- package/docs/test-your-program.md +52 -0
- package/docs/testing.md +1 -1
- package/docs/troubleshooting.md +7 -0
- package/lib/typesol.d.ts +325 -13
- package/package.json +19 -1
- package/runtime/typesol_rt.h +54 -9
- package/ts-plugin/index.js +112 -0
- package/ts-plugin/package.json +4 -0
package/dist/compiler/model.d.ts
CHANGED
|
@@ -110,9 +110,11 @@ export type FieldType = ScalarType | {
|
|
|
110
110
|
name: string;
|
|
111
111
|
}
|
|
112
112
|
/** `Vec<T>`: Borsh u32 length + elements. Only as the last field of an account struct. */
|
|
113
|
+
/** `Vec<T>` (last field, grows the account) or, with `cap`, `FixedVec<T, N>`: a u32 length and room for N elements. */
|
|
113
114
|
| {
|
|
114
115
|
kind: "vec";
|
|
115
116
|
elem: FieldType;
|
|
117
|
+
cap?: number;
|
|
116
118
|
};
|
|
117
119
|
export interface StructField {
|
|
118
120
|
name: string;
|
|
@@ -136,6 +138,11 @@ export interface StructDef {
|
|
|
136
138
|
accountDiscriminator: number[];
|
|
137
139
|
eventDiscriminator: number[];
|
|
138
140
|
node: ts.InterfaceDeclaration;
|
|
141
|
+
/**
|
|
142
|
+
* How account data stores it: "fixed" (every field at a fixed offset, the default) or "borsh" (`@layout borsh`:
|
|
143
|
+
* Anchor's bytes, where strings, Vecs and Options take only what they hold).
|
|
144
|
+
*/
|
|
145
|
+
layout: "fixed" | "borsh";
|
|
139
146
|
}
|
|
140
147
|
export type TokenProgramKind = "token" | "token2022" | "tokenInterface";
|
|
141
148
|
export type ParamKind = {
|
|
@@ -278,7 +285,11 @@ export interface Instruction {
|
|
|
278
285
|
args: ArgParam[];
|
|
279
286
|
/** Fixed bytes of the arguments; strings add their length on top. */
|
|
280
287
|
minArgsSize: number;
|
|
281
|
-
|
|
288
|
+
/** Sent as return data: a scalar in Borsh, or a fixed-size struct in its fixed layout (as the IDL describes it). */
|
|
289
|
+
returns: ScalarType | {
|
|
290
|
+
kind: "struct";
|
|
291
|
+
name: string;
|
|
292
|
+
} | undefined;
|
|
282
293
|
/** account name -> seeds, recorded when the body creates or verifies a PDA with describable seeds. */
|
|
283
294
|
pdas: Map<string, IdlSeed[]>;
|
|
284
295
|
/** account name -> the program its PDA is derived under, when not this program (e.g. associated token accounts). */
|
|
@@ -287,6 +298,14 @@ export interface Instruction {
|
|
|
287
298
|
/** The declaring file's `typesol` imports (local name -> export name). */
|
|
288
299
|
imports: Map<string, string>;
|
|
289
300
|
}
|
|
301
|
+
/** A helper with type parameters, before it is instantiated. */
|
|
302
|
+
export interface GenericHelper {
|
|
303
|
+
name: string;
|
|
304
|
+
display: string;
|
|
305
|
+
node: HelperNode;
|
|
306
|
+
typeParams: string[];
|
|
307
|
+
imports: Map<string, string>;
|
|
308
|
+
}
|
|
290
309
|
export interface HelperParam {
|
|
291
310
|
name: string;
|
|
292
311
|
/** `{ kind: "account" }` for account parameters (then `account` says which kind). */
|
|
@@ -294,12 +313,28 @@ export interface HelperParam {
|
|
|
294
313
|
account?: ParamKind;
|
|
295
314
|
node: ts.ParameterDeclaration;
|
|
296
315
|
}
|
|
297
|
-
/** A
|
|
316
|
+
/** A function written as `function f(…)`, `const f = (…) => …` or `const f = function (…) {…}`. */
|
|
317
|
+
export type HelperNode = ts.FunctionDeclaration | ts.ArrowFunction | ts.FunctionExpression;
|
|
318
|
+
/**
|
|
319
|
+
* A non-exported function (or any function of an imported file), or an arrow function declared with const at the top
|
|
320
|
+
* level or inside a function (capturing nothing): values and accounts in; void, a scalar or a struct out.
|
|
321
|
+
*/
|
|
298
322
|
export interface Helper {
|
|
323
|
+
/** The C name (fn_<name>): the function's name, `outer__local` for a local arrow, `name__u64` for an instance. */
|
|
299
324
|
name: string;
|
|
325
|
+
/** The name in messages: `local`, `max<u64>`. */
|
|
326
|
+
display: string;
|
|
300
327
|
params: HelperParam[];
|
|
301
|
-
|
|
302
|
-
|
|
328
|
+
/** A struct result is written through an out pointer (`TSS_<name> *ret`) that the caller provides. */
|
|
329
|
+
returns: ScalarType | {
|
|
330
|
+
kind: "struct";
|
|
331
|
+
name: string;
|
|
332
|
+
} | undefined;
|
|
333
|
+
node: HelperNode;
|
|
334
|
+
/** The body; an arrow's expression body is one return (or expression) statement. */
|
|
335
|
+
statements: readonly ts.Statement[];
|
|
336
|
+
/** A generic helper's instance: type parameter -> the type it stands for. */
|
|
337
|
+
typeArgs?: Map<string, ScalarType>;
|
|
303
338
|
/** The declaring file's `typesol` imports (local name -> export name). */
|
|
304
339
|
imports: Map<string, string>;
|
|
305
340
|
}
|
|
@@ -322,6 +357,11 @@ export interface DataEnumDef {
|
|
|
322
357
|
}[];
|
|
323
358
|
/** Largest variant size: the fixed payload in account data. */
|
|
324
359
|
payload: number;
|
|
360
|
+
/**
|
|
361
|
+
* A variant holds a `string` (directly or in a nested enum): such an enum is Borsh in instruction arguments and
|
|
362
|
+
* events and a local value otherwise, never account data or part of a fixed layout. Its C payload holds TS_Str views.
|
|
363
|
+
*/
|
|
364
|
+
variable?: boolean;
|
|
325
365
|
node: ts.TypeAliasDeclaration;
|
|
326
366
|
}
|
|
327
367
|
/** A unit-variant enum: `export enum Status { Open, Closed }`. */
|
|
@@ -339,6 +379,10 @@ export interface ProgramModel {
|
|
|
339
379
|
structs: Map<string, StructDef>;
|
|
340
380
|
instructions: Instruction[];
|
|
341
381
|
helpers: Map<string, Helper>;
|
|
382
|
+
/** Generic helpers by name: instantiated (into `helpers`) for the types each call uses. */
|
|
383
|
+
generics: Map<string, GenericHelper>;
|
|
384
|
+
/** Declaration (function, or the const of an arrow) -> helper or generic name, for calls to local arrows. */
|
|
385
|
+
helperDecls: Map<ts.Node, string>;
|
|
342
386
|
errors: ErrorDef[];
|
|
343
387
|
/** Enum name -> member name -> error */
|
|
344
388
|
errorEnums: Map<string, Map<string, ErrorDef>>;
|
|
@@ -361,6 +405,10 @@ export interface ProgramModel {
|
|
|
361
405
|
argStructs: Set<string>;
|
|
362
406
|
/** FixedString capacities in use, for C typedefs and IDL types. */
|
|
363
407
|
fstrings: Set<number>;
|
|
408
|
+
/** FixedVec<T, N> types in use (IDL name -> type), for IDL types. */
|
|
409
|
+
fixedVecs: Map<string, FieldType & {
|
|
410
|
+
kind: "vec";
|
|
411
|
+
}>;
|
|
364
412
|
}
|
|
365
413
|
export declare function isWritable(k: ParamKind): boolean;
|
|
366
414
|
export declare function typeName(t: ValueType | FieldType): string;
|
|
@@ -373,3 +421,7 @@ export declare function optionKey(t: ScalarType | {
|
|
|
373
421
|
name: string;
|
|
374
422
|
}): string;
|
|
375
423
|
export declare function scalarKey(t: ScalarType): string;
|
|
424
|
+
/** The IDL type name of a FixedVec<T, N>: `FixedVec<N>_<T>`. */
|
|
425
|
+
export declare function fixedVecName(t: FieldType & {
|
|
426
|
+
kind: "vec";
|
|
427
|
+
}): string;
|
package/dist/compiler/model.js
CHANGED
|
@@ -56,7 +56,7 @@ export function typeName(t) {
|
|
|
56
56
|
case "enumRef":
|
|
57
57
|
return t.name;
|
|
58
58
|
case "vec":
|
|
59
|
-
return `Vec<${typeName(t.elem)}>`;
|
|
59
|
+
return t.cap === undefined ? `Vec<${typeName(t.elem)}>` : `FixedVec<${typeName(t.elem)}, ${t.cap}>`;
|
|
60
60
|
case "vecArg":
|
|
61
61
|
return `Vec<${typeName(t.elem)}>`;
|
|
62
62
|
case "arrayArg":
|
|
@@ -92,7 +92,7 @@ export function sameType(a, b) {
|
|
|
92
92
|
case "option":
|
|
93
93
|
return sameType(a.inner, b.inner);
|
|
94
94
|
case "vec":
|
|
95
|
-
return sameType(a.elem, b.elem);
|
|
95
|
+
return a.cap === b.cap && sameType(a.elem, b.elem);
|
|
96
96
|
case "vecArg":
|
|
97
97
|
return sameType(a.elem, b.elem);
|
|
98
98
|
case "arrayArg":
|
|
@@ -120,3 +120,9 @@ export function optionKey(t) {
|
|
|
120
120
|
export function scalarKey(t) {
|
|
121
121
|
return t.kind === "int" ? t.name : t.kind === "enum" ? `e_${t.name}` : t.kind === "pubkey" && t.hash ? "hash" : t.kind;
|
|
122
122
|
}
|
|
123
|
+
/** The IDL type name of a FixedVec<T, N>: `FixedVec<N>_<T>`. */
|
|
124
|
+
export function fixedVecName(t) {
|
|
125
|
+
return `FixedVec${t.cap}_${typeName(t.elem)
|
|
126
|
+
.replace(/[^A-Za-z0-9]+/g, "_")
|
|
127
|
+
.replace(/_+$/, "")}`;
|
|
128
|
+
}
|
|
@@ -14,6 +14,8 @@ export interface Toolchain {
|
|
|
14
14
|
/** Locate the Solana C SDK that ships with the Agave CLI's platform-tools. */
|
|
15
15
|
export declare function findToolchain(sbpf?: Sbpf): Toolchain;
|
|
16
16
|
/** Compile generated C to an SBF shared object (same flags as the SDK's sbf.mk for the chosen SBPF version). */
|
|
17
|
+
/** The SBF stack frame of one function. */
|
|
18
|
+
export declare const STACK_FRAME = 4096;
|
|
17
19
|
export declare function buildSharedObject(cFile: string, outSo: string, sbpf?: Sbpf, tc?: Toolchain): void;
|
|
18
20
|
/** The clang version string, for build manifests. */
|
|
19
21
|
export declare function toolchainVersion(tc?: Toolchain): string;
|
|
@@ -51,6 +51,8 @@ export function findToolchain(sbpf = "v0") {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
/** Compile generated C to an SBF shared object (same flags as the SDK's sbf.mk for the chosen SBPF version). */
|
|
54
|
+
/** The SBF stack frame of one function. */
|
|
55
|
+
export const STACK_FRAME = 4096;
|
|
54
56
|
export function buildSharedObject(cFile, outSo, sbpf = "v0", tc = findToolchain(sbpf)) {
|
|
55
57
|
const obj = outSo.replace(/\.so$/, ".o");
|
|
56
58
|
const cflags = [
|
|
@@ -58,6 +60,9 @@ export function buildSharedObject(cFile, outSo, sbpf = "v0", tc = findToolchain(
|
|
|
58
60
|
"-Wno-parentheses-equality",
|
|
59
61
|
// Generated checks may be always true/false (`a === a`, `enumByte >= 256` for a 256-variant enum); that is not an error.
|
|
60
62
|
"-Wno-tautological-compare",
|
|
63
|
+
// SBPF v0 gives every function a fixed 4 KiB stack frame; past it the program corrupts memory instead of failing.
|
|
64
|
+
// v1 and v2 grow frames dynamically, so the limit does not apply there.
|
|
65
|
+
...(sbpf === "v0" ? [`-Wframe-larger-than=${STACK_FRAME}`] : []),
|
|
61
66
|
"-O2",
|
|
62
67
|
"-fno-builtin",
|
|
63
68
|
// One section per function and constant, so the linker's --gc-sections can drop what nothing reaches.
|
|
@@ -70,7 +75,12 @@ export function buildSharedObject(cFile, outSo, sbpf = "v0", tc = findToolchain(
|
|
|
70
75
|
...(sbpf === "v0" ? [] : [`-mcpu=${sbpf}`]),
|
|
71
76
|
];
|
|
72
77
|
const incs = tc.includes.flatMap((i, n) => (n < 2 ? ["-isystem", i] : ["-I", i]));
|
|
73
|
-
|
|
78
|
+
try {
|
|
79
|
+
run(tc.clang, [...cflags, ...incs, "-o", obj, "-c", cFile]);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
throw stackError(e.message) ?? e;
|
|
83
|
+
}
|
|
74
84
|
run(tc.lld, [
|
|
75
85
|
"-z",
|
|
76
86
|
"notext",
|
|
@@ -99,6 +109,22 @@ export function buildSharedObject(cFile, outSo, sbpf = "v0", tc = findToolchain(
|
|
|
99
109
|
export function toolchainVersion(tc = findToolchain()) {
|
|
100
110
|
return execFileSync(tc.clang, ["--version"], { encoding: "utf8" }).split("\n")[0].trim();
|
|
101
111
|
}
|
|
112
|
+
/** clang's frame-size errors, in the program's terms: which instruction or helper, how much, what to do. */
|
|
113
|
+
function stackError(message) {
|
|
114
|
+
const over = [...message.matchAll(/stack frame size \((\d+)\) exceeds limit \((\d+)\) in '(\w+)'/g)];
|
|
115
|
+
if (!over.length)
|
|
116
|
+
return undefined;
|
|
117
|
+
// clang inlines helpers into their callers, so an instruction's frame includes theirs.
|
|
118
|
+
const what = (fn) => fn.startsWith("ix_") ? `instruction ${fn.slice(3)} (with the helpers inlined into it)` : fn.startsWith("fn_") ? `helper ${fn.slice(3)}()` : fn;
|
|
119
|
+
// Anything else clang reported in the same run stays in the message.
|
|
120
|
+
const rest = message
|
|
121
|
+
.split("\n")
|
|
122
|
+
.filter((l) => / error: /.test(l) && !/-Wframe-larger-than/.test(l))
|
|
123
|
+
.join("\n");
|
|
124
|
+
return new Error(over.map((m) => `${what(m[3])} needs ${m[1]} bytes of stack; SBPF v0 gives each function ${m[2]}`).join("\n") +
|
|
125
|
+
"\nKeep large structs and arrays in account data: bind them with const (a reference) instead of a typed local copy, or split the work into helpers." +
|
|
126
|
+
(rest ? `\n${rest}` : ""));
|
|
127
|
+
}
|
|
102
128
|
function run(cmd, args) {
|
|
103
129
|
try {
|
|
104
130
|
execFileSync(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A deployed program read straight from a cluster, for `typesol verify --address`: its ELF bytes and who can still
|
|
3
|
+
* change them. Handles the three loaders a program can live under:
|
|
4
|
+
*
|
|
5
|
+
* - upgradeable (loader v3, what `solana program deploy` uses): the program account points at a ProgramData account
|
|
6
|
+
* holding the deploy slot, the upgrade authority (none once frozen) and then the ELF;
|
|
7
|
+
* - loader v4: one account holding the slot, the authority, the status and then the ELF;
|
|
8
|
+
* - the old non-upgradeable loader (v2): the account data is the ELF itself.
|
|
9
|
+
*/
|
|
10
|
+
import type { Rpc, SolanaRpcApi } from "@solana/kit";
|
|
11
|
+
export declare const LOADER_V2 = "BPFLoader2111111111111111111111111111111111";
|
|
12
|
+
export declare const LOADER_V3 = "BPFLoaderUpgradeab1e11111111111111111111111";
|
|
13
|
+
export declare const LOADER_V4 = "LoaderV411111111111111111111111111111111111";
|
|
14
|
+
export interface Deployed {
|
|
15
|
+
loader: "v2" | "v3" | "v4";
|
|
16
|
+
/** The ELF as stored (loader v3 keeps it zero-padded to the account's allocation). */
|
|
17
|
+
elf: Buffer;
|
|
18
|
+
/** Who can upgrade or close it; null when the program is immutable. */
|
|
19
|
+
authority: string | null;
|
|
20
|
+
/** The slot of the last deploy or upgrade (v3, v4). */
|
|
21
|
+
slot?: bigint;
|
|
22
|
+
/** Where the bytes live (the ProgramData account for v3). */
|
|
23
|
+
dataAccount: string;
|
|
24
|
+
}
|
|
25
|
+
type AccountRpc = Pick<Rpc<SolanaRpcApi>, "getAccountInfo">;
|
|
26
|
+
/** The deployed program at `programId`, or an error that says why there is none. */
|
|
27
|
+
export declare function fetchDeployed(rpc: AccountRpc, programId: string): Promise<Deployed>;
|
|
28
|
+
/** JSON with object keys sorted, so two IDLs compare by content and not by key order. */
|
|
29
|
+
export declare function canonicalJson(v: unknown): string;
|
|
30
|
+
export {};
|
package/dist/onchain.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getAddressDecoder } from "@solana/kit";
|
|
2
|
+
export const LOADER_V2 = "BPFLoader2111111111111111111111111111111111";
|
|
3
|
+
export const LOADER_V3 = "BPFLoaderUpgradeab1e11111111111111111111111";
|
|
4
|
+
export const LOADER_V4 = "LoaderV411111111111111111111111111111111111";
|
|
5
|
+
async function account(rpc, address) {
|
|
6
|
+
const { value } = await rpc.getAccountInfo(address, { encoding: "base64", commitment: "confirmed" }).send();
|
|
7
|
+
if (!value)
|
|
8
|
+
return null;
|
|
9
|
+
return { owner: value.owner, data: Buffer.from(value.data[0], "base64") };
|
|
10
|
+
}
|
|
11
|
+
const key = (data, offset) => getAddressDecoder().decode(data.subarray(offset, offset + 32));
|
|
12
|
+
/** The deployed program at `programId`, or an error that says why there is none. */
|
|
13
|
+
export async function fetchDeployed(rpc, programId) {
|
|
14
|
+
const program = await account(rpc, programId);
|
|
15
|
+
if (!program)
|
|
16
|
+
throw new Error(`no account at ${programId} on this cluster`);
|
|
17
|
+
if (program.owner === LOADER_V2)
|
|
18
|
+
return { loader: "v2", elf: program.data, authority: null, dataAccount: programId };
|
|
19
|
+
if (program.owner === LOADER_V4) {
|
|
20
|
+
// u64 slot, authority (or next version), u64 status (0 retracted, 1 deployed, 2 finalized), then the ELF.
|
|
21
|
+
if (program.data.length < 48)
|
|
22
|
+
throw new Error(`${programId} is not a loader-v4 program`);
|
|
23
|
+
const status = program.data.readBigUInt64LE(40);
|
|
24
|
+
if (status === 0n)
|
|
25
|
+
throw new Error(`${programId} is retracted (loader v4): it has no executable code`);
|
|
26
|
+
return {
|
|
27
|
+
loader: "v4",
|
|
28
|
+
elf: program.data.subarray(48),
|
|
29
|
+
authority: status === 2n ? null : key(program.data, 8),
|
|
30
|
+
slot: program.data.readBigUInt64LE(0),
|
|
31
|
+
dataAccount: programId,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (program.owner !== LOADER_V3)
|
|
35
|
+
throw new Error(`${programId} is not a program (owner ${program.owner})`);
|
|
36
|
+
// Program account: u32 state = 2, ProgramData address.
|
|
37
|
+
if (program.data.length < 36 || program.data.readUInt32LE(0) !== 2)
|
|
38
|
+
throw new Error(`${programId} is an upgradeable-loader account but not a program`);
|
|
39
|
+
const dataAccount = key(program.data, 4);
|
|
40
|
+
const pd = await account(rpc, dataAccount);
|
|
41
|
+
// ProgramData: u32 state = 3, u64 slot, Option<Pubkey> authority (1 + 32 bytes), then the ELF.
|
|
42
|
+
if (!pd || pd.owner !== LOADER_V3 || pd.data.length < 45 || pd.data.readUInt32LE(0) !== 3)
|
|
43
|
+
throw new Error(`${programId} has no program data (closed or never deployed)`);
|
|
44
|
+
return { loader: "v3", elf: pd.data.subarray(45), authority: pd.data[12] ? key(pd.data, 13) : null, slot: pd.data.readBigUInt64LE(4), dataAccount };
|
|
45
|
+
}
|
|
46
|
+
/** JSON with object keys sorted, so two IDLs compare by content and not by key order. */
|
|
47
|
+
export function canonicalJson(v) {
|
|
48
|
+
return JSON.stringify(v, (_k, x) => x && typeof x === "object" && !Array.isArray(x)
|
|
49
|
+
? Object.fromEntries(Object.keys(x)
|
|
50
|
+
.sort()
|
|
51
|
+
.map((k) => [k, x[k]]))
|
|
52
|
+
: x);
|
|
53
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
type IdlType = string | {
|
|
2
|
+
vec?: IdlType;
|
|
3
|
+
option?: IdlType;
|
|
4
|
+
coption?: IdlType;
|
|
5
|
+
array?: [IdlType, number | unknown];
|
|
6
|
+
defined?: string | {
|
|
7
|
+
name: string;
|
|
8
|
+
generics?: unknown[];
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
interface IdlField {
|
|
12
|
+
name: string;
|
|
13
|
+
type: IdlType;
|
|
14
|
+
docs?: string[];
|
|
15
|
+
}
|
|
16
|
+
interface IdlTypeDef {
|
|
17
|
+
name: string;
|
|
18
|
+
docs?: string[];
|
|
19
|
+
type: {
|
|
20
|
+
kind: string;
|
|
21
|
+
fields?: (IdlField | IdlType)[];
|
|
22
|
+
variants?: {
|
|
23
|
+
name: string;
|
|
24
|
+
fields?: (IdlField | IdlType)[];
|
|
25
|
+
}[];
|
|
26
|
+
};
|
|
27
|
+
generics?: unknown[];
|
|
28
|
+
}
|
|
29
|
+
interface IdlAccountItem {
|
|
30
|
+
name: string;
|
|
31
|
+
writable?: boolean;
|
|
32
|
+
signer?: boolean;
|
|
33
|
+
optional?: boolean;
|
|
34
|
+
address?: string;
|
|
35
|
+
docs?: string[];
|
|
36
|
+
pda?: {
|
|
37
|
+
seeds: {
|
|
38
|
+
kind: string;
|
|
39
|
+
value?: number[];
|
|
40
|
+
path?: string;
|
|
41
|
+
}[];
|
|
42
|
+
program?: unknown;
|
|
43
|
+
};
|
|
44
|
+
relations?: string[];
|
|
45
|
+
accounts?: IdlAccountItem[];
|
|
46
|
+
}
|
|
47
|
+
interface IdlInstruction {
|
|
48
|
+
name: string;
|
|
49
|
+
docs?: string[];
|
|
50
|
+
discriminator: number[];
|
|
51
|
+
accounts: IdlAccountItem[];
|
|
52
|
+
args: IdlField[];
|
|
53
|
+
returns?: IdlType;
|
|
54
|
+
}
|
|
55
|
+
export interface PortIdl {
|
|
56
|
+
address?: string;
|
|
57
|
+
metadata?: {
|
|
58
|
+
name?: string;
|
|
59
|
+
};
|
|
60
|
+
instructions: IdlInstruction[];
|
|
61
|
+
accounts?: {
|
|
62
|
+
name: string;
|
|
63
|
+
discriminator: number[];
|
|
64
|
+
}[];
|
|
65
|
+
events?: {
|
|
66
|
+
name: string;
|
|
67
|
+
discriminator: number[];
|
|
68
|
+
}[];
|
|
69
|
+
errors?: {
|
|
70
|
+
code: number;
|
|
71
|
+
name: string;
|
|
72
|
+
msg?: string;
|
|
73
|
+
}[];
|
|
74
|
+
types?: IdlTypeDef[];
|
|
75
|
+
constants?: {
|
|
76
|
+
name: string;
|
|
77
|
+
type: IdlType;
|
|
78
|
+
value: string;
|
|
79
|
+
}[];
|
|
80
|
+
}
|
|
81
|
+
export interface PortResult {
|
|
82
|
+
source: string;
|
|
83
|
+
/** What the skeleton cannot carry over as is, and where Anchor clients would see a different layout. */
|
|
84
|
+
notes: string[];
|
|
85
|
+
}
|
|
86
|
+
export declare function generatePort(idl: PortIdl): PortResult;
|
|
87
|
+
export {};
|