@typesol/cli 0.16.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 +46 -0
- package/README.md +3 -3
- package/dist/clientgen.js +37 -0
- package/dist/compiler/analyze.d.ts +7 -1
- package/dist/compiler/analyze.js +258 -30
- package/dist/compiler/emit/base.d.ts +7 -0
- package/dist/compiler/emit/base.js +61 -1
- package/dist/compiler/emit/borsh.d.ts +13 -0
- package/dist/compiler/emit/borsh.js +232 -0
- package/dist/compiler/emit/calls.js +43 -15
- package/dist/compiler/emit/cpi.d.ts +32 -8
- package/dist/compiler/emit/cpi.js +522 -20
- package/dist/compiler/emit/expressions.js +19 -2
- package/dist/compiler/emit/function.js +34 -11
- package/dist/compiler/emit/program.js +24 -6
- package/dist/compiler/emit/shared.d.ts +12 -0
- package/dist/compiler/emit/shared.js +19 -2
- package/dist/compiler/emit/statements.js +11 -3
- package/dist/compiler/emit/storage.d.ts +4 -0
- package/dist/compiler/emit/storage.js +60 -12
- package/dist/compiler/idl.js +33 -4
- package/dist/compiler/model.d.ts +41 -2
- package/dist/compiler/model.js +8 -2
- package/dist/portgen.js +60 -4
- package/docs/errors.md +3 -2
- package/docs/language.md +10 -6
- package/docs/migrate-from-anchor.md +14 -5
- package/docs/test-your-program.md +1 -1
- package/lib/typesol.d.ts +259 -3
- package/package.json +1 -1
- package/runtime/typesol_rt.h +32 -7
package/lib/typesol.d.ts
CHANGED
|
@@ -77,6 +77,24 @@ export interface Vec<T> {
|
|
|
77
77
|
[Symbol.iterator](): Iterator<T>;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* A list stored inline with room for N elements: a u32 length, then N slots (Anchor `Vec<T>` with `#[max_len(N)]`, but
|
|
82
|
+
* always 4 + N × size(T) bytes). Unlike `Vec<T>` it can be any field, any number of times, and in nested structs;
|
|
83
|
+
* `push` fails (5104) when it is full. Write a whole one with `fixedVec([a, b])`.
|
|
84
|
+
*/
|
|
85
|
+
export interface FixedVec<T, N extends number> {
|
|
86
|
+
readonly length: u64;
|
|
87
|
+
get(index: bigint): T;
|
|
88
|
+
set(index: bigint, value: T): void;
|
|
89
|
+
push(value: T): void;
|
|
90
|
+
pop(): T;
|
|
91
|
+
clear(): void;
|
|
92
|
+
[Symbol.iterator](): Iterator<T>;
|
|
93
|
+
readonly __capacity?: N;
|
|
94
|
+
}
|
|
95
|
+
/** A FixedVec value holding these elements (`acct.owners = fixedVec([a, b])`, `{ owners: fixedVec([]) }`). */
|
|
96
|
+
export declare function fixedVec<T>(items: T[]): FixedVec<T, never>;
|
|
97
|
+
|
|
80
98
|
/** One extra account passed after the declared ones. Nothing about it is checked until you check it. */
|
|
81
99
|
export interface RemainingAccount {
|
|
82
100
|
readonly key: Pubkey;
|
|
@@ -233,7 +251,10 @@ export interface TokenMetadataProgram extends AccountMeta {
|
|
|
233
251
|
isMutable: boolean,
|
|
234
252
|
signerSeeds?: Seed[] | SignerSeeds,
|
|
235
253
|
): void;
|
|
236
|
-
/**
|
|
254
|
+
/**
|
|
255
|
+
* With creators (1–5, shares adding up to 100), an unverified collection mint, and/or `isCollection: true`
|
|
256
|
+
* (CollectionDetails::V1: this NFT is a sized collection other NFTs are verified into).
|
|
257
|
+
*/
|
|
237
258
|
createV3(
|
|
238
259
|
metadata: AccountMeta,
|
|
239
260
|
mint: AccountMeta,
|
|
@@ -246,10 +267,42 @@ export interface TokenMetadataProgram extends AccountMeta {
|
|
|
246
267
|
uri: string,
|
|
247
268
|
sellerFeeBasisPoints: u16,
|
|
248
269
|
isMutable: boolean,
|
|
249
|
-
extras: { creators?: MetadataCreator[]; collection?: Pubkey },
|
|
270
|
+
extras: { creators?: MetadataCreator[]; collection?: Pubkey; isCollection?: boolean },
|
|
271
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
272
|
+
): void;
|
|
273
|
+
/**
|
|
274
|
+
* CreateMasterEditionV3: makes `mint` (supply 1, decimals 0) a master edition; the mint and freeze authorities move
|
|
275
|
+
* to the edition. `maxSupply` 0n is a one of one, `null` allows unlimited prints.
|
|
276
|
+
*/
|
|
277
|
+
createMasterEditionV3(
|
|
278
|
+
edition: AccountMeta,
|
|
279
|
+
mint: AccountMeta,
|
|
280
|
+
updateAuthority: AccountMeta,
|
|
281
|
+
mintAuthority: AccountMeta,
|
|
282
|
+
payer: Mut<Signer>,
|
|
283
|
+
metadata: AccountMeta,
|
|
284
|
+
tokenProgram: TokenProgram,
|
|
285
|
+
systemProgram: SystemProgram,
|
|
286
|
+
maxSupply: u64 | null,
|
|
287
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
288
|
+
): void;
|
|
289
|
+
/**
|
|
290
|
+
* Verify with CollectionV1: marks `metadata`'s collection (set with createV3's `collection`) verified. `authority` is
|
|
291
|
+
* the collection's update authority; the collection is a master edition created with `isCollection: true`.
|
|
292
|
+
*/
|
|
293
|
+
verifyCollection(
|
|
294
|
+
authority: AccountMeta,
|
|
295
|
+
metadata: AccountMeta,
|
|
296
|
+
collectionMint: AccountMeta,
|
|
297
|
+
collectionMetadata: AccountMeta,
|
|
298
|
+
collectionMasterEdition: AccountMeta,
|
|
299
|
+
systemProgram: SystemProgram,
|
|
300
|
+
instructionsSysvar: AccountMeta,
|
|
250
301
|
signerSeeds?: Seed[] | SignerSeeds,
|
|
251
302
|
): void;
|
|
252
303
|
}
|
|
304
|
+
/** The Metaplex master edition address of a mint (PDA ["metadata", program, mint, "edition"]). */
|
|
305
|
+
export declare function masterEditionAddress(mint: Pubkey): Pubkey;
|
|
253
306
|
/** The canonical program address of `seeds` under `program` (Rust `Pubkey::find_program_address(seeds, program).0`). */
|
|
254
307
|
export declare function findProgramAddress(seeds: Seed[], program: Pubkey): Pubkey;
|
|
255
308
|
/** The Metaplex metadata account address of a mint. */
|
|
@@ -473,9 +526,36 @@ export declare function emitCpi<T>(event: T, eventAuthority: EventAuthority, sel
|
|
|
473
526
|
* account out. Accounts that sign (the new asset/collection, authorities) are keypair Signers, or PDAs of this
|
|
474
527
|
* program covered by `signerSeeds`.
|
|
475
528
|
*/
|
|
529
|
+
/**
|
|
530
|
+
* Who manages a Metaplex Core plugin: `"owner"`, `"updateAuthority"`, `"none"` (nobody: fixed), or an address. Left out,
|
|
531
|
+
* the plugin type's default (the owner for owner-managed plugins, the update authority for the others).
|
|
532
|
+
*/
|
|
533
|
+
export type CorePluginAuthority = "none" | "owner" | "updateAuthority" | Pubkey;
|
|
534
|
+
/** A Metaplex Core plugin, written as an object literal (Core's Plugin enum, with its authority when it is added). */
|
|
535
|
+
export type CorePlugin = (
|
|
536
|
+
| { kind: "Royalties"; basisPoints: u16; creators: { address: Pubkey; percentage: u8 }[] }
|
|
537
|
+
| { kind: "FreezeDelegate"; frozen: boolean }
|
|
538
|
+
| { kind: "BurnDelegate" }
|
|
539
|
+
| { kind: "TransferDelegate" }
|
|
540
|
+
| { kind: "UpdateDelegate"; additionalDelegates?: Pubkey[] }
|
|
541
|
+
| { kind: "PermanentFreezeDelegate"; frozen: boolean }
|
|
542
|
+
| { kind: "Attributes"; attributes: { key: string; value: string }[] }
|
|
543
|
+
| { kind: "PermanentTransferDelegate" }
|
|
544
|
+
| { kind: "PermanentBurnDelegate" }
|
|
545
|
+
| { kind: "Edition"; number: u32 }
|
|
546
|
+
| { kind: "AddBlocker" }
|
|
547
|
+
| { kind: "ImmutableMetadata" }
|
|
548
|
+
/** On a collection: lets Bubblegum mint compressed NFTs into it (mintV2 with a collection). */
|
|
549
|
+
| { kind: "BubblegumV2" }
|
|
550
|
+
) & { authority?: CorePluginAuthority };
|
|
551
|
+
export type CorePluginKind = CorePlugin["kind"] | "MasterEdition" | "VerifiedCreators" | "Autograph";
|
|
552
|
+
|
|
476
553
|
export interface MplCoreProgram extends AccountMeta {
|
|
477
554
|
readonly __mpl_core: void;
|
|
478
|
-
/**
|
|
555
|
+
/**
|
|
556
|
+
* CreateV1. In a collection, `authority` is the collection's update authority; `owner` defaults to the payer.
|
|
557
|
+
* `plugins` (a literal list, one of each kind) are created with the asset.
|
|
558
|
+
*/
|
|
479
559
|
createAsset(
|
|
480
560
|
asset: AccountMeta,
|
|
481
561
|
collection: AccountMeta | null,
|
|
@@ -487,6 +567,28 @@ export interface MplCoreProgram extends AccountMeta {
|
|
|
487
567
|
uri: string,
|
|
488
568
|
signerSeeds?: Seed[] | SignerSeeds,
|
|
489
569
|
): void;
|
|
570
|
+
createAsset(
|
|
571
|
+
asset: AccountMeta,
|
|
572
|
+
collection: AccountMeta | null,
|
|
573
|
+
authority: AccountMeta | null,
|
|
574
|
+
payer: Mut<Signer>,
|
|
575
|
+
owner: AccountMeta | null,
|
|
576
|
+
systemProgram: SystemProgram,
|
|
577
|
+
name: string,
|
|
578
|
+
uri: string,
|
|
579
|
+
plugins: CorePlugin[],
|
|
580
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
581
|
+
): void;
|
|
582
|
+
createCollection(
|
|
583
|
+
collection: AccountMeta,
|
|
584
|
+
updateAuthority: AccountMeta | null,
|
|
585
|
+
payer: Mut<Signer>,
|
|
586
|
+
systemProgram: SystemProgram,
|
|
587
|
+
name: string,
|
|
588
|
+
uri: string,
|
|
589
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
590
|
+
): void;
|
|
591
|
+
/** With plugins every asset of the collection inherits (Royalties, PermanentFreezeDelegate, …). */
|
|
490
592
|
createCollection(
|
|
491
593
|
collection: AccountMeta,
|
|
492
594
|
updateAuthority: AccountMeta | null,
|
|
@@ -494,6 +596,60 @@ export interface MplCoreProgram extends AccountMeta {
|
|
|
494
596
|
systemProgram: SystemProgram,
|
|
495
597
|
name: string,
|
|
496
598
|
uri: string,
|
|
599
|
+
plugins: CorePlugin[],
|
|
600
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
601
|
+
): void;
|
|
602
|
+
/** AddPluginV1, signed by `authority` (`null`: the payer): the owner for owner-managed plugins, else the update authority. */
|
|
603
|
+
addPlugin(
|
|
604
|
+
asset: AccountMeta,
|
|
605
|
+
collection: AccountMeta | null,
|
|
606
|
+
payer: Mut<Signer>,
|
|
607
|
+
authority: AccountMeta | null,
|
|
608
|
+
systemProgram: SystemProgram,
|
|
609
|
+
plugin: CorePlugin,
|
|
610
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
611
|
+
): void;
|
|
612
|
+
/** UpdatePluginV1: new values for a plugin the asset has (no `authority`), e.g. `{ kind: "FreezeDelegate", frozen: true }`. */
|
|
613
|
+
updatePlugin(
|
|
614
|
+
asset: AccountMeta,
|
|
615
|
+
collection: AccountMeta | null,
|
|
616
|
+
payer: Mut<Signer>,
|
|
617
|
+
authority: AccountMeta | null,
|
|
618
|
+
systemProgram: SystemProgram,
|
|
619
|
+
plugin: CorePlugin,
|
|
620
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
621
|
+
): void;
|
|
622
|
+
removePlugin(
|
|
623
|
+
asset: AccountMeta,
|
|
624
|
+
collection: AccountMeta | null,
|
|
625
|
+
payer: Mut<Signer>,
|
|
626
|
+
authority: AccountMeta | null,
|
|
627
|
+
systemProgram: SystemProgram,
|
|
628
|
+
kind: CorePluginKind,
|
|
629
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
630
|
+
): void;
|
|
631
|
+
addCollectionPlugin(
|
|
632
|
+
collection: AccountMeta,
|
|
633
|
+
payer: Mut<Signer>,
|
|
634
|
+
authority: AccountMeta | null,
|
|
635
|
+
systemProgram: SystemProgram,
|
|
636
|
+
plugin: CorePlugin,
|
|
637
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
638
|
+
): void;
|
|
639
|
+
updateCollectionPlugin(
|
|
640
|
+
collection: AccountMeta,
|
|
641
|
+
payer: Mut<Signer>,
|
|
642
|
+
authority: AccountMeta | null,
|
|
643
|
+
systemProgram: SystemProgram,
|
|
644
|
+
plugin: CorePlugin,
|
|
645
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
646
|
+
): void;
|
|
647
|
+
removeCollectionPlugin(
|
|
648
|
+
collection: AccountMeta,
|
|
649
|
+
payer: Mut<Signer>,
|
|
650
|
+
authority: AccountMeta | null,
|
|
651
|
+
systemProgram: SystemProgram,
|
|
652
|
+
kind: CorePluginKind,
|
|
497
653
|
signerSeeds?: Seed[] | SignerSeeds,
|
|
498
654
|
): void;
|
|
499
655
|
/** TransferV1, signed by the owner (or a delegate) as `authority` (`null`: the payer). */
|
|
@@ -548,6 +704,106 @@ export interface BubblegumProgram extends AccountMeta {
|
|
|
548
704
|
sellerFeeBasisPoints: u16,
|
|
549
705
|
signerSeeds?: Seed[] | SignerSeeds,
|
|
550
706
|
): void;
|
|
707
|
+
/**
|
|
708
|
+
* CreateTreeConfigV2: a tree on mpl-account-compression (mcmt6…, allocated by the client and owned by it) with the
|
|
709
|
+
* mpl-noop log wrapper (mnoop…). `treeCreator` `null`: the payer.
|
|
710
|
+
*/
|
|
711
|
+
createTreeV2(
|
|
712
|
+
treeConfig: AccountMeta,
|
|
713
|
+
merkleTree: AccountMeta,
|
|
714
|
+
payer: Mut<Signer>,
|
|
715
|
+
treeCreator: AccountMeta | null,
|
|
716
|
+
logWrapper: AccountMeta,
|
|
717
|
+
compressionProgram: AccountMeta,
|
|
718
|
+
systemProgram: SystemProgram,
|
|
719
|
+
maxDepth: u32,
|
|
720
|
+
maxBufferSize: u32,
|
|
721
|
+
isPublic: boolean,
|
|
722
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
723
|
+
): void;
|
|
724
|
+
/** MintV2 of a leaf, optionally into a Metaplex Core collection (whose update authority signs as `authority`). */
|
|
725
|
+
mintV2(
|
|
726
|
+
treeConfig: AccountMeta,
|
|
727
|
+
payer: Mut<Signer>,
|
|
728
|
+
treeDelegate: AccountMeta | null,
|
|
729
|
+
leafOwner: AccountMeta,
|
|
730
|
+
leafDelegate: AccountMeta | null,
|
|
731
|
+
merkleTree: AccountMeta,
|
|
732
|
+
logWrapper: AccountMeta,
|
|
733
|
+
compressionProgram: AccountMeta,
|
|
734
|
+
mplCoreProgram: AccountMeta,
|
|
735
|
+
systemProgram: SystemProgram,
|
|
736
|
+
metadata: CompressedMetadata,
|
|
737
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
738
|
+
): void;
|
|
739
|
+
mintV2(
|
|
740
|
+
treeConfig: AccountMeta,
|
|
741
|
+
payer: Mut<Signer>,
|
|
742
|
+
treeDelegate: AccountMeta | null,
|
|
743
|
+
leafOwner: AccountMeta,
|
|
744
|
+
leafDelegate: AccountMeta | null,
|
|
745
|
+
merkleTree: AccountMeta,
|
|
746
|
+
logWrapper: AccountMeta,
|
|
747
|
+
compressionProgram: AccountMeta,
|
|
748
|
+
mplCoreProgram: AccountMeta,
|
|
749
|
+
systemProgram: SystemProgram,
|
|
750
|
+
metadata: CompressedMetadata,
|
|
751
|
+
collection: { collection: AccountMeta; authority: AccountMeta; cpiSigner: AccountMeta },
|
|
752
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
753
|
+
): void;
|
|
754
|
+
/** TransferV2, signed by the owner or delegate as `authority` (`null`: the payer); `proof` is the leaf's Merkle proof. */
|
|
755
|
+
transferV2(
|
|
756
|
+
treeConfig: AccountMeta,
|
|
757
|
+
payer: Mut<Signer>,
|
|
758
|
+
authority: AccountMeta | null,
|
|
759
|
+
leafOwner: AccountMeta,
|
|
760
|
+
leafDelegate: AccountMeta | null,
|
|
761
|
+
newLeafOwner: AccountMeta,
|
|
762
|
+
merkleTree: AccountMeta,
|
|
763
|
+
coreCollection: AccountMeta | null,
|
|
764
|
+
logWrapper: AccountMeta,
|
|
765
|
+
compressionProgram: AccountMeta,
|
|
766
|
+
systemProgram: SystemProgram,
|
|
767
|
+
leaf: CompressedLeaf,
|
|
768
|
+
proof: RemainingAccounts | RemainingSlice,
|
|
769
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
770
|
+
): void;
|
|
771
|
+
burnV2(
|
|
772
|
+
treeConfig: AccountMeta,
|
|
773
|
+
payer: Mut<Signer>,
|
|
774
|
+
authority: AccountMeta | null,
|
|
775
|
+
leafOwner: AccountMeta,
|
|
776
|
+
leafDelegate: AccountMeta | null,
|
|
777
|
+
merkleTree: AccountMeta,
|
|
778
|
+
coreCollection: AccountMeta | null,
|
|
779
|
+
mplCoreCpiSigner: AccountMeta | null,
|
|
780
|
+
logWrapper: AccountMeta,
|
|
781
|
+
compressionProgram: AccountMeta,
|
|
782
|
+
mplCoreProgram: AccountMeta,
|
|
783
|
+
systemProgram: SystemProgram,
|
|
784
|
+
leaf: CompressedLeaf,
|
|
785
|
+
proof: RemainingAccounts | RemainingSlice,
|
|
786
|
+
signerSeeds?: Seed[] | SignerSeeds,
|
|
787
|
+
): void;
|
|
788
|
+
}
|
|
789
|
+
/** Bubblegum V2 leaf metadata (MetadataArgsV2): non-fungible, primary sale not happened, mutable unless `isMutable: false`. */
|
|
790
|
+
export interface CompressedMetadata {
|
|
791
|
+
name: string;
|
|
792
|
+
symbol: string;
|
|
793
|
+
uri: string;
|
|
794
|
+
sellerFeeBasisPoints: u16;
|
|
795
|
+
creators?: { address: Pubkey; verified: boolean; share: u8 }[];
|
|
796
|
+
isMutable?: boolean;
|
|
797
|
+
}
|
|
798
|
+
/** The leaf a transfer or burn replaces, as an indexer (DAS getAssetProof / getAsset) reports it. */
|
|
799
|
+
export interface CompressedLeaf {
|
|
800
|
+
root: Hash;
|
|
801
|
+
dataHash: Hash;
|
|
802
|
+
creatorHash: Hash;
|
|
803
|
+
assetDataHash?: Hash | null;
|
|
804
|
+
flags?: u8 | null;
|
|
805
|
+
nonce: u64;
|
|
806
|
+
index: u32;
|
|
551
807
|
}
|
|
552
808
|
|
|
553
809
|
/** The current slot and epoch (Clock sysvar). */
|
package/package.json
CHANGED
package/runtime/typesol_rt.h
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
#define TS_ERR_ALREADY_INITIALIZED 3000 /* AccountDiscriminatorAlreadySet */
|
|
35
35
|
#define TS_ERR_DISCRIMINATOR 3002 /* AccountDiscriminatorMismatch */
|
|
36
36
|
#define TS_ERR_ACCOUNT_TOO_SMALL 3003 /* AccountDidNotDeserialize */
|
|
37
|
+
#define TS_ERR_DID_NOT_SERIALIZE 3004 /* AccountDidNotSerialize */
|
|
37
38
|
#define TS_ERR_TOKEN_ACCOUNT 3003 /* AccountDidNotDeserialize (not an initialized token account) */
|
|
38
39
|
#define TS_ERR_MINT 3003 /* AccountDidNotDeserialize (not an initialized mint) */
|
|
39
40
|
#define TS_ERR_NOT_ENOUGH_ACCOUNTS 3005 /* AccountNotEnoughKeys */
|
|
@@ -162,8 +163,11 @@ static inline TS_Str ts_str(const uint8_t *ptr, uint64_t len) {
|
|
|
162
163
|
static inline bool ts_utf8_valid(const uint8_t *p, uint64_t n) {
|
|
163
164
|
uint64_t i = 0;
|
|
164
165
|
while (i < n) {
|
|
166
|
+
/* ASCII eight bytes at a time (no high bit set), then byte by byte up to the next multi-byte sequence. */
|
|
167
|
+
while (i + 8 <= n && (ts_ld64(p + i) & 0x8080808080808080ULL) == 0) i += 8;
|
|
168
|
+
while (i < n && p[i] < 0x80) i++;
|
|
169
|
+
if (i == n) break;
|
|
165
170
|
uint8_t c = p[i];
|
|
166
|
-
if (c < 0x80) { i++; continue; }
|
|
167
171
|
uint64_t len;
|
|
168
172
|
uint32_t cp;
|
|
169
173
|
if (c >= 0xc2 && c <= 0xdf) { len = 2; cp = c & 0x1f; }
|
|
@@ -670,16 +674,17 @@ static inline uint64_t ts_realloc(TsParams *params, TsAccount *payer, TsAccount
|
|
|
670
674
|
return ts_resize(params, payer, acct, new_len, entry_len);
|
|
671
675
|
}
|
|
672
676
|
|
|
677
|
+
/* `space` for a new account; an existing one needs `min_space` (less for a @layout borsh account). */
|
|
673
678
|
static inline uint64_t ts_create_pda_if_needed(TsParams *params, TsAccount *payer, TsAccount *acct,
|
|
674
679
|
SolSignerSeed *seeds, int n, const uint8_t disc[8], uint64_t space,
|
|
675
|
-
uint8_t *bump_out, bool *created) {
|
|
680
|
+
uint64_t min_space, uint8_t *bump_out, bool *created) {
|
|
676
681
|
if (ts_key_eq(&acct->owner, params->program_id)) {
|
|
677
682
|
SolPubkey derived;
|
|
678
683
|
uint8_t bump;
|
|
679
684
|
if (ts_find_pda(seeds, n, params->program_id, &derived, &bump) != SUCCESS ||
|
|
680
685
|
!ts_key_eq(&derived, &acct->key))
|
|
681
686
|
TS_FAIL(TS_ERR_SEEDS, "TypeSOL: PDA seeds do not match account");
|
|
682
|
-
if (acct->data_len <
|
|
687
|
+
if (acct->data_len < min_space) TS_FAIL(TS_ERR_ACCOUNT_TOO_SMALL, "TypeSOL: account data too small");
|
|
683
688
|
if (!ts_mem_eq(acct->data, disc, 8)) TS_FAIL(TS_ERR_DISCRIMINATOR, "TypeSOL: account discriminator mismatch");
|
|
684
689
|
*bump_out = bump;
|
|
685
690
|
*created = false;
|
|
@@ -1209,9 +1214,21 @@ static inline uint64_t ts_metadata_address(const SolPubkey *mint, SolPubkey *out
|
|
|
1209
1214
|
return SUCCESS;
|
|
1210
1215
|
}
|
|
1211
1216
|
|
|
1217
|
+
static inline uint64_t ts_master_edition_address(const SolPubkey *mint, SolPubkey *out) {
|
|
1218
|
+
SolSignerSeed seeds[4] = {{(const uint8_t *)"metadata", 8},
|
|
1219
|
+
{(const uint8_t *)&TS_MPL_METADATA_ID, 32},
|
|
1220
|
+
{(const uint8_t *)mint, 32},
|
|
1221
|
+
{(const uint8_t *)"edition", 7}};
|
|
1222
|
+
uint8_t bump;
|
|
1223
|
+
if (ts_find_pda(seeds, 4, &TS_MPL_METADATA_ID, out, &bump) != SUCCESS)
|
|
1224
|
+
TS_FAIL(TS_ERR_SEEDS, "TypeSOL: cannot derive the master edition address");
|
|
1225
|
+
return SUCCESS;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1212
1228
|
/*
|
|
1213
1229
|
* Metaplex CreateMetadataAccountV3 (instruction 33): DataV2 { name, symbol, uri, seller_fee_basis_points u16,
|
|
1214
|
-
* creators Option<Vec<Creator>>, collection Option<Collection>, uses None }, is_mutable bool, collection_details
|
|
1230
|
+
* creators Option<Vec<Creator>>, collection Option<Collection>, uses None }, is_mutable bool, collection_details
|
|
1231
|
+
* None, or Some(V1 { size: 0 }) when `sized_collection`.
|
|
1215
1232
|
* `creators` holds `ncreators` packed Creator records (address, verified, share: 34 bytes); ncreators < 0 is None.
|
|
1216
1233
|
* `collection` (NULL for None) is written unverified, as Metaplex requires at creation.
|
|
1217
1234
|
* Accounts: metadata (w), mint, mint authority (s), payer (ws), update authority, system program.
|
|
@@ -1220,10 +1237,10 @@ static inline uint64_t ts_mpl_create_v3(TsParams *params, const TsAccount *progr
|
|
|
1220
1237
|
TsAccount *mint, TsAccount *mint_authority, TsAccount *payer,
|
|
1221
1238
|
TsAccount *update_authority, TsAccount *system, TS_Str name, TS_Str symbol,
|
|
1222
1239
|
TS_Str uri, uint16_t fee_bps, bool is_mutable, const uint8_t *creators, int ncreators,
|
|
1223
|
-
const SolPubkey *collection, const SolSignerSeed *seeds, int n) {
|
|
1240
|
+
const SolPubkey *collection, bool sized_collection, const SolSignerSeed *seeds, int n) {
|
|
1224
1241
|
uint8_t *data;
|
|
1225
1242
|
uint64_t ncr = ncreators > 0 ? (uint64_t)ncreators : 0;
|
|
1226
|
-
TS_TRY(ts_alloc(1 + 12 + name.len + symbol.len + uri.len + 2 + (1 + 4 + 34 * ncr) + (1 + 33) + 1 + 1 + 1, &data));
|
|
1243
|
+
TS_TRY(ts_alloc(1 + 12 + name.len + symbol.len + uri.len + 2 + (1 + 4 + 34 * ncr) + (1 + 33) + 1 + 1 + (1 + 9), &data));
|
|
1227
1244
|
uint64_t at = 0;
|
|
1228
1245
|
data[at++] = 33;
|
|
1229
1246
|
ts_put_str(data, &at, name);
|
|
@@ -1251,7 +1268,15 @@ static inline uint64_t ts_mpl_create_v3(TsParams *params, const TsAccount *progr
|
|
|
1251
1268
|
}
|
|
1252
1269
|
data[at++] = 0; /* uses: None */
|
|
1253
1270
|
data[at++] = is_mutable ? 1 : 0;
|
|
1254
|
-
|
|
1271
|
+
if (sized_collection) {
|
|
1272
|
+
/* collection_details: Some(V1 { size: 0 }): this NFT is a collection items can be verified into */
|
|
1273
|
+
data[at++] = 1;
|
|
1274
|
+
data[at++] = 0;
|
|
1275
|
+
ts_memzero(data + at, 8);
|
|
1276
|
+
at += 8;
|
|
1277
|
+
} else {
|
|
1278
|
+
data[at++] = 0; /* collection_details: None */
|
|
1279
|
+
}
|
|
1255
1280
|
bool ua_signs = update_authority->is_signer || ts_key_eq(&update_authority->key, &mint_authority->key);
|
|
1256
1281
|
SolAccountMeta metas[6] = {{&metadata->key, true, false}, {&mint->key, false, false},
|
|
1257
1282
|
{&mint_authority->key, false, true}, {&payer->key, true, true},
|