@pizzaton/ton 0.0.0-stage → 0.1.1

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.
Files changed (98) hide show
  1. package/CONTRACTS.md +239 -0
  2. package/README.md +505 -2
  3. package/dist/airdrop/index.d.mts +18 -0
  4. package/dist/airdrop/index.mjs +86 -0
  5. package/dist/connect/errors.d.mts +4 -0
  6. package/dist/connect/errors.mjs +21 -0
  7. package/dist/connect/index.d.mts +23 -0
  8. package/dist/connect/index.mjs +34 -0
  9. package/dist/contracts/catalog/index.d.mts +361 -0
  10. package/dist/contracts/catalog/index.mjs +403 -0
  11. package/dist/contracts/client.d.mts +18 -0
  12. package/dist/contracts/client.mjs +31 -0
  13. package/dist/contracts/codecs.d.mts +14 -0
  14. package/dist/contracts/codecs.mjs +61 -0
  15. package/dist/contracts/hipo.d.mts +138 -0
  16. package/dist/contracts/hipo.mjs +198 -0
  17. package/dist/contracts/index.d.mts +23 -0
  18. package/dist/contracts/index.mjs +20 -0
  19. package/dist/contracts/metadata.d.mts +38 -0
  20. package/dist/contracts/metadata.mjs +50 -0
  21. package/dist/contracts/module-client.d.mts +20 -0
  22. package/dist/contracts/module-client.mjs +34 -0
  23. package/dist/contracts/module.d.mts +8 -0
  24. package/dist/contracts/module.mjs +11 -0
  25. package/dist/contracts/wrappers/base.d.mts +18 -0
  26. package/dist/contracts/wrappers/base.mjs +31 -0
  27. package/dist/contracts/wrappers/index.d.mts +12 -0
  28. package/dist/contracts/wrappers/index.mjs +12 -0
  29. package/dist/contracts/wrappers/jvault-protocols.d.mts +206 -0
  30. package/dist/contracts/wrappers/jvault-protocols.mjs +432 -0
  31. package/dist/contracts/wrappers/jvault-support.d.mts +135 -0
  32. package/dist/contracts/wrappers/jvault-support.mjs +269 -0
  33. package/dist/contracts/wrappers/jvault.d.mts +123 -0
  34. package/dist/contracts/wrappers/jvault.mjs +258 -0
  35. package/dist/contracts/wrappers/memeland.d.mts +253 -0
  36. package/dist/contracts/wrappers/memeland.mjs +396 -0
  37. package/dist/contracts/wrappers/multix.d.mts +92 -0
  38. package/dist/contracts/wrappers/multix.mjs +156 -0
  39. package/dist/contracts/wrappers/pizzabox.d.mts +66 -0
  40. package/dist/contracts/wrappers/pizzabox.mjs +105 -0
  41. package/dist/contracts/wrappers/ton-raffles.d.mts +215 -0
  42. package/dist/contracts/wrappers/ton-raffles.mjs +398 -0
  43. package/dist/contracts/wrappers/tonresistor.d.mts +189 -0
  44. package/dist/contracts/wrappers/tonresistor.mjs +276 -0
  45. package/dist/core/address.d.mts +31 -0
  46. package/dist/core/address.mjs +53 -0
  47. package/dist/core/amount.d.mts +8 -0
  48. package/dist/core/amount.mjs +34 -0
  49. package/dist/core/bytes.d.mts +5 -0
  50. package/dist/core/bytes.mjs +18 -0
  51. package/dist/core/constants.d.mts +14 -0
  52. package/dist/core/constants.mjs +15 -0
  53. package/dist/core/errors.d.mts +9 -0
  54. package/dist/core/errors.mjs +16 -0
  55. package/dist/core/http.mjs +39 -0
  56. package/dist/core/index.d.mts +8 -0
  57. package/dist/core/index.mjs +8 -0
  58. package/dist/core/metadata.d.mts +12 -0
  59. package/dist/core/metadata.mjs +35 -0
  60. package/dist/core/network.d.mts +24 -0
  61. package/dist/core/network.mjs +41 -0
  62. package/dist/emulator/index.d.mts +20 -0
  63. package/dist/emulator/index.mjs +24 -0
  64. package/dist/index.d.mts +21 -0
  65. package/dist/index.mjs +19 -0
  66. package/dist/indexer/index.d.mts +90 -0
  67. package/dist/indexer/index.mjs +279 -0
  68. package/dist/jetton/details.d.mts +27 -0
  69. package/dist/jetton/details.mjs +116 -0
  70. package/dist/jetton/index.d.mts +54 -0
  71. package/dist/jetton/index.mjs +92 -0
  72. package/dist/jetton/versions.d.mts +12 -0
  73. package/dist/jetton/versions.mjs +50 -0
  74. package/dist/nft/collection.d.mts +57 -0
  75. package/dist/nft/collection.mjs +148 -0
  76. package/dist/nft/content.d.mts +34 -0
  77. package/dist/nft/content.mjs +142 -0
  78. package/dist/nft/index.d.mts +35 -0
  79. package/dist/nft/index.mjs +51 -0
  80. package/dist/nft/versions.d.mts +11 -0
  81. package/dist/nft/versions.mjs +29 -0
  82. package/dist/proof/index.d.mts +62 -0
  83. package/dist/proof/index.mjs +227 -0
  84. package/dist/provider/index.d.mts +32 -0
  85. package/dist/provider/index.mjs +1 -0
  86. package/dist/react/index.d.mts +13 -0
  87. package/dist/react/index.mjs +48 -0
  88. package/dist/server/index.d.mts +11 -0
  89. package/dist/server/index.mjs +55 -0
  90. package/dist/simulation/index.d.mts +112 -0
  91. package/dist/simulation/index.mjs +310 -0
  92. package/dist/transactions/index.d.mts +33 -0
  93. package/dist/transactions/index.mjs +51 -0
  94. package/dist/vesting/index.d.mts +12 -0
  95. package/dist/vesting/index.mjs +25 -0
  96. package/dist/wallet/index.d.mts +23 -0
  97. package/dist/wallet/index.mjs +71 -0
  98. package/package.json +176 -5
@@ -0,0 +1,54 @@
1
+ import { TokenMetadata } from "../core/metadata.mjs";
2
+ import { TonProvider } from "../provider/index.mjs";
3
+ import { JETTON_IMPLEMENTATION_PROFILES, JettonImplementationProfile, JettonImplementationVersion, getJettonImplementationProfile } from "./versions.mjs";
4
+ import { Address, Cell, ContractProvider, Sender, TupleBuilder } from "@ton/core";
5
+ import { JettonMaster, JettonMaster as JettonMaster$1, JettonMaster as JettonMasterContract, JettonWallet } from "@ton/ton";
6
+ //#region src/jetton/index.d.ts
7
+ export declare const JETTON_OPCODES: {
8
+ readonly transfer: 260734629;
9
+ readonly burn: 1499400124;
10
+ readonly excesses: 3576854235;
11
+ readonly internalTransfer: 395134233;
12
+ readonly transferNotification: 1935855772;
13
+ };
14
+ export interface JettonTransferInput {
15
+ readonly amount: bigint;
16
+ readonly destination: Address;
17
+ readonly responseDestination: Address;
18
+ readonly queryId?: bigint;
19
+ readonly forwardAmount?: bigint;
20
+ readonly customPayload?: Cell;
21
+ readonly forwardPayload?: Cell;
22
+ }
23
+ export interface JettonBurnInput {
24
+ readonly amount: bigint;
25
+ readonly responseDestination: Address;
26
+ readonly queryId?: bigint;
27
+ readonly customPayload?: Cell;
28
+ }
29
+ export type JettonMetadata = TokenMetadata;
30
+ export type JettonData = Awaited<ReturnType<JettonMaster$1["getJettonData"]>>;
31
+ export interface JettonWalletData {
32
+ readonly balance: bigint;
33
+ readonly owner: Address;
34
+ readonly master: Address;
35
+ readonly walletCode: Cell;
36
+ }
37
+ export declare class JettonWalletContract {
38
+ readonly address: Address;
39
+ private readonly official;
40
+ private constructor();
41
+ static create(address: Address): JettonWalletContract;
42
+ getBalance(provider: ContractProvider): Promise<bigint>;
43
+ getWalletData(provider: ContractProvider): Promise<JettonWalletData>;
44
+ sendTransfer(provider: ContractProvider, via: Sender, input: JettonTransferInput, value: bigint): Promise<void>;
45
+ sendBurn(provider: ContractProvider, via: Sender, input: JettonBurnInput, value: bigint): Promise<void>;
46
+ }
47
+ export declare function buildJettonTransferBody(input: JettonTransferInput): Cell;
48
+ export declare function buildJettonBurnBody(input: JettonBurnInput): Cell;
49
+ export declare function buildJettonExcessesBody(queryId?: bigint): Cell;
50
+ export declare function buildJettonGetWalletAddressArgs(owner: Address): TupleBuilder;
51
+ export declare function resolveJettonWalletAddress(provider: TonProvider, master: Address, owner: Address): Promise<Address>;
52
+ export declare function parseJettonAmount(value: string, decimals: number): bigint;
53
+ //#endregion
54
+ export { JETTON_IMPLEMENTATION_PROFILES, JettonImplementationProfile, JettonImplementationVersion, type JettonMaster, type JettonMasterContract, JettonWallet, getJettonImplementationProfile };
@@ -0,0 +1,92 @@
1
+ import { invariant } from "../core/errors.mjs";
2
+ import { MAX_TON_COINS, assertTonAmount, parseUnits } from "../core/amount.mjs";
3
+ import { JETTON_IMPLEMENTATION_PROFILES, getJettonImplementationProfile } from "./versions.mjs";
4
+ import { SendMode, TupleBuilder, beginCell } from "@ton/core";
5
+ import { JettonMaster, JettonMaster as JettonMasterContract, JettonWallet, JettonWallet as JettonWallet$1 } from "@ton/ton";
6
+ //#region src/jetton/index.ts
7
+ const JETTON_OPCODES = {
8
+ transfer: 260734629,
9
+ burn: 1499400124,
10
+ excesses: 3576854235,
11
+ internalTransfer: 395134233,
12
+ transferNotification: 1935855772
13
+ };
14
+ var JettonWalletContract = class JettonWalletContract {
15
+ address;
16
+ official;
17
+ constructor(address) {
18
+ this.official = JettonWallet$1.create(address);
19
+ this.address = this.official.address;
20
+ }
21
+ static create(address) {
22
+ return new JettonWalletContract(address);
23
+ }
24
+ async getBalance(provider) {
25
+ return this.official.getBalance(provider);
26
+ }
27
+ async getWalletData(provider) {
28
+ const { stack } = await provider.get("get_wallet_data", []);
29
+ return {
30
+ balance: stack.readBigNumber(),
31
+ owner: stack.readAddress(),
32
+ master: stack.readAddress(),
33
+ walletCode: stack.readCell()
34
+ };
35
+ }
36
+ async sendTransfer(provider, via, input, value) {
37
+ assertTonAmount(value, "Jetton transfer value");
38
+ await provider.internal(via, {
39
+ value,
40
+ body: buildJettonTransferBody(input),
41
+ sendMode: SendMode.PAY_GAS_SEPARATELY
42
+ });
43
+ }
44
+ async sendBurn(provider, via, input, value) {
45
+ assertTonAmount(value, "Jetton burn value");
46
+ await provider.internal(via, {
47
+ value,
48
+ body: buildJettonBurnBody(input),
49
+ sendMode: SendMode.PAY_GAS_SEPARATELY
50
+ });
51
+ }
52
+ };
53
+ function buildJettonTransferBody(input) {
54
+ assertAmount(input.amount);
55
+ assertQueryId(input.queryId);
56
+ const forwardAmount = input.forwardAmount ?? 0n;
57
+ invariant(forwardAmount >= 0n && forwardAmount <= MAX_TON_COINS, "INVALID_AMOUNT", "Forward amount is outside the TON coin range");
58
+ const builder = beginCell().storeUint(JETTON_OPCODES.transfer, 32).storeUint(input.queryId ?? 0n, 64).storeCoins(input.amount).storeAddress(input.destination).storeAddress(input.responseDestination).storeMaybeRef(input.customPayload).storeCoins(forwardAmount);
59
+ if (input.forwardPayload) builder.storeBit(1).storeRef(input.forwardPayload);
60
+ else builder.storeBit(0);
61
+ return builder.endCell();
62
+ }
63
+ function buildJettonBurnBody(input) {
64
+ assertAmount(input.amount);
65
+ assertQueryId(input.queryId);
66
+ return beginCell().storeUint(JETTON_OPCODES.burn, 32).storeUint(input.queryId ?? 0n, 64).storeCoins(input.amount).storeAddress(input.responseDestination).storeMaybeRef(input.customPayload).endCell();
67
+ }
68
+ function buildJettonExcessesBody(queryId = 0n) {
69
+ assertQueryId(queryId);
70
+ return beginCell().storeUint(JETTON_OPCODES.excesses, 32).storeUint(queryId, 64).endCell();
71
+ }
72
+ function buildJettonGetWalletAddressArgs(owner) {
73
+ const tuple = new TupleBuilder();
74
+ tuple.writeAddress(owner);
75
+ return tuple;
76
+ }
77
+ async function resolveJettonWalletAddress(provider, master, owner) {
78
+ const result = await provider.runGetMethod(master, "get_wallet_address", buildJettonGetWalletAddressArgs(owner).build());
79
+ invariant(result.exitCode === void 0 || result.exitCode === 0, "PROVIDER_ERROR", `Jetton wallet address getter failed with exit code ${result.exitCode}`, { exitCode: result.exitCode });
80
+ return result.stack.readAddress();
81
+ }
82
+ function parseJettonAmount(value, decimals) {
83
+ return parseUnits(value, decimals);
84
+ }
85
+ function assertAmount(value) {
86
+ invariant(value >= 0n && value <= MAX_TON_COINS, "INVALID_AMOUNT", "Jetton amount is out of range");
87
+ }
88
+ function assertQueryId(value) {
89
+ if (value !== void 0) invariant(value >= 0n && value < 2n ** 64n, "INVALID_TRANSACTION", "Query id is out of range");
90
+ }
91
+ //#endregion
92
+ export { JETTON_IMPLEMENTATION_PROFILES, JETTON_OPCODES, JettonMaster, JettonMasterContract, JettonWallet, JettonWalletContract, buildJettonBurnBody, buildJettonExcessesBody, buildJettonGetWalletAddressArgs, buildJettonTransferBody, getJettonImplementationProfile, parseJettonAmount, resolveJettonWalletAddress };
@@ -0,0 +1,12 @@
1
+ //#region src/jetton/versions.d.ts
2
+ export type JettonImplementationVersion = "jetton-1.0" | "discoverable" | "stablecoin" | "notcoin" | "mintless" | "jetton-2.0";
3
+ export interface JettonImplementationProfile {
4
+ readonly version: JettonImplementationVersion;
5
+ readonly supportsWalletDiscovery: boolean;
6
+ readonly supportsBurn: boolean;
7
+ readonly supportsCustomTransferPayload: boolean;
8
+ readonly optimizedWalletSharding: boolean;
9
+ }
10
+ export declare const JETTON_IMPLEMENTATION_PROFILES: Readonly<Record<JettonImplementationVersion, JettonImplementationProfile>>;
11
+ export declare function getJettonImplementationProfile(version: JettonImplementationVersion): JettonImplementationProfile;
12
+ //#endregion
@@ -0,0 +1,50 @@
1
+ //#region src/jetton/versions.ts
2
+ const JETTON_IMPLEMENTATION_PROFILES = Object.freeze({
3
+ "jetton-1.0": {
4
+ version: "jetton-1.0",
5
+ supportsWalletDiscovery: false,
6
+ supportsBurn: true,
7
+ supportsCustomTransferPayload: true,
8
+ optimizedWalletSharding: false
9
+ },
10
+ discoverable: {
11
+ version: "discoverable",
12
+ supportsWalletDiscovery: true,
13
+ supportsBurn: true,
14
+ supportsCustomTransferPayload: true,
15
+ optimizedWalletSharding: false
16
+ },
17
+ stablecoin: {
18
+ version: "stablecoin",
19
+ supportsWalletDiscovery: true,
20
+ supportsBurn: false,
21
+ supportsCustomTransferPayload: true,
22
+ optimizedWalletSharding: false
23
+ },
24
+ notcoin: {
25
+ version: "notcoin",
26
+ supportsWalletDiscovery: true,
27
+ supportsBurn: true,
28
+ supportsCustomTransferPayload: true,
29
+ optimizedWalletSharding: false
30
+ },
31
+ mintless: {
32
+ version: "mintless",
33
+ supportsWalletDiscovery: true,
34
+ supportsBurn: true,
35
+ supportsCustomTransferPayload: true,
36
+ optimizedWalletSharding: false
37
+ },
38
+ "jetton-2.0": {
39
+ version: "jetton-2.0",
40
+ supportsWalletDiscovery: true,
41
+ supportsBurn: true,
42
+ supportsCustomTransferPayload: true,
43
+ optimizedWalletSharding: true
44
+ }
45
+ });
46
+ function getJettonImplementationProfile(version) {
47
+ return JETTON_IMPLEMENTATION_PROFILES[version];
48
+ }
49
+ //#endregion
50
+ export { JETTON_IMPLEMENTATION_PROFILES, getJettonImplementationProfile };
@@ -0,0 +1,57 @@
1
+ import { NftContent, RoyaltyParameters } from "./content.mjs";
2
+ import { Address, Cell, Contract, ContractProvider, Sender } from "@ton/core";
3
+ //#region src/nft/collection.d.ts
4
+ export declare const NFT_COLLECTION_OPCODES: {
5
+ readonly deployItem: 1;
6
+ readonly batchDeployItem: 2;
7
+ readonly changeOwner: 3;
8
+ readonly getRoyaltyParams: 1765620048;
9
+ };
10
+ export interface NftCollectionConfig {
11
+ readonly admin: Address;
12
+ readonly content: NftContent | Cell;
13
+ readonly commonContent: string;
14
+ readonly itemCode: Cell;
15
+ readonly royalty: RoyaltyParameters;
16
+ }
17
+ export interface NewNftItem {
18
+ readonly owner: Address;
19
+ readonly content: NftContent | Cell;
20
+ }
21
+ export interface NftCollectionData {
22
+ readonly nextItemIndex: bigint;
23
+ readonly collectionContent: Cell;
24
+ readonly owner: Address;
25
+ }
26
+ export declare function collectionConfigToCell(config: NftCollectionConfig): Cell;
27
+ export declare function buildNftDeployItemBody(item: NewNftItem, index: bigint | number, forwardAmount: bigint, queryId?: bigint | number): Cell;
28
+ export declare function buildNftChangeOwnerBody(newOwner: Address, queryId?: bigint | number): Cell;
29
+ export declare function buildNftBatchDeployBody(items: readonly {
30
+ readonly index: bigint | number;
31
+ readonly item: NewNftItem;
32
+ readonly forwardAmount: bigint;
33
+ }[], queryId?: bigint | number): Cell;
34
+ export declare function buildNftRoyaltyParamsBody(queryId?: bigint | number): Cell;
35
+ export declare class NftCollectionContract implements Contract {
36
+ readonly init?: {
37
+ readonly code: Cell;
38
+ readonly data: Cell;
39
+ } | undefined;
40
+ readonly address: Address;
41
+ private constructor();
42
+ static createFromAddress(address: Address): NftCollectionContract;
43
+ static createFromConfig(config: NftCollectionConfig, code: Cell, workchain?: number): NftCollectionContract;
44
+ sendDeploy(provider: ContractProvider, via: Sender, value: bigint): Promise<void>;
45
+ sendDeployItem(provider: ContractProvider, via: Sender, item: NewNftItem, index: bigint | number, forwardAmount?: bigint, value?: bigint, queryId?: bigint | number): Promise<void>;
46
+ sendChangeOwner(provider: ContractProvider, via: Sender, newOwner: Address, value?: bigint, queryId?: bigint | number): Promise<void>;
47
+ sendDeployBatch(provider: ContractProvider, via: Sender, items: readonly {
48
+ readonly item: NewNftItem;
49
+ readonly index: bigint | number;
50
+ readonly forwardAmount: bigint;
51
+ }[], value: bigint, queryId?: bigint | number): Promise<void>;
52
+ sendGetRoyaltyParams(provider: ContractProvider, via: Sender, value?: bigint, queryId?: bigint | number): Promise<void>;
53
+ getNftAddressByIndex(provider: ContractProvider, index: bigint | number): Promise<Address>;
54
+ getCollectionData(provider: ContractProvider): Promise<NftCollectionData>;
55
+ getNftContent(provider: ContractProvider, index: bigint | number, content: Cell): Promise<Cell>;
56
+ }
57
+ //#endregion
@@ -0,0 +1,148 @@
1
+ import { invariant } from "../core/errors.mjs";
2
+ import { MAX_TON_COINS, assertTonAmount } from "../core/amount.mjs";
3
+ import { nftContentToCell, royaltyParamsToCell } from "./content.mjs";
4
+ import { Cell, Dictionary, SendMode, beginCell, contractAddress, toNano } from "@ton/core";
5
+ //#region src/nft/collection.ts
6
+ const NFT_COLLECTION_OPCODES = {
7
+ deployItem: 1,
8
+ batchDeployItem: 2,
9
+ changeOwner: 3,
10
+ getRoyaltyParams: 1765620048
11
+ };
12
+ function collectionConfigToCell(config) {
13
+ return beginCell().storeAddress(config.admin).storeUint(0, 64).storeRef(beginCell().storeRef(config.content instanceof Cell ? config.content : nftContentToCell(config.content)).storeRef(beginCell().storeStringTail(config.commonContent).endCell()).endCell()).storeRef(config.itemCode).storeRef(royaltyParamsToCell(config.royalty)).endCell();
14
+ }
15
+ function assertQueryId(queryId) {
16
+ invariant(typeof queryId === "bigint" || Number.isSafeInteger(queryId), "INVALID_TRANSACTION", "Query id must be a safe integer");
17
+ const value = BigInt(queryId);
18
+ invariant(value >= 0n && value < 2n ** 64n, "INVALID_TRANSACTION", "Query id is out of range");
19
+ return value;
20
+ }
21
+ function assertIndex(index) {
22
+ invariant(typeof index === "bigint" || Number.isSafeInteger(index), "INVALID_TRANSACTION", "NFT index must be a safe integer");
23
+ const value = BigInt(index);
24
+ invariant(value >= 0n && value < 2n ** 64n, "INVALID_TRANSACTION", "NFT index is out of range");
25
+ return value;
26
+ }
27
+ function buildNftDeployItemBody(item, index, forwardAmount, queryId = 0n) {
28
+ invariant(forwardAmount >= 0n && forwardAmount <= MAX_TON_COINS, "INVALID_AMOUNT", "Forward amount is outside the TON coin range");
29
+ return beginCell().storeUint(NFT_COLLECTION_OPCODES.deployItem, 32).storeUint(assertQueryId(queryId), 64).storeUint(assertIndex(index), 64).storeCoins(forwardAmount).storeRef(beginCell().storeAddress(item.owner).storeRef(item.content instanceof Cell ? item.content : nftContentToCell(item.content)).endCell()).endCell();
30
+ }
31
+ function buildNftChangeOwnerBody(newOwner, queryId = 0n) {
32
+ return beginCell().storeUint(NFT_COLLECTION_OPCODES.changeOwner, 32).storeUint(assertQueryId(queryId), 64).storeAddress(newOwner).endCell();
33
+ }
34
+ function batchDeployValue() {
35
+ return {
36
+ parse(slice) {
37
+ const content = slice.loadRef().beginParse();
38
+ return {
39
+ forwardAmount: slice.loadCoins(),
40
+ owner: content.loadAddress(),
41
+ content: content.loadRef()
42
+ };
43
+ },
44
+ serialize(value, builder) {
45
+ invariant(value.forwardAmount >= 0n && value.forwardAmount <= MAX_TON_COINS, "INVALID_AMOUNT", "Forward amount is outside the TON coin range");
46
+ builder.storeCoins(value.forwardAmount).storeRef(beginCell().storeAddress(value.owner).storeRef(value.content instanceof Cell ? value.content : nftContentToCell(value.content)).endCell());
47
+ }
48
+ };
49
+ }
50
+ function buildNftBatchDeployBody(items, queryId = 0n) {
51
+ const dictionary = Dictionary.empty(Dictionary.Keys.BigUint(64), batchDeployValue());
52
+ for (const entry of items) {
53
+ invariant(entry.forwardAmount >= 0n && entry.forwardAmount <= MAX_TON_COINS, "INVALID_AMOUNT", "Forward amount is outside the TON coin range");
54
+ dictionary.set(assertIndex(entry.index), {
55
+ ...entry.item,
56
+ forwardAmount: entry.forwardAmount
57
+ });
58
+ }
59
+ return beginCell().storeUint(NFT_COLLECTION_OPCODES.batchDeployItem, 32).storeUint(assertQueryId(queryId), 64).storeDict(dictionary).endCell();
60
+ }
61
+ function buildNftRoyaltyParamsBody(queryId = 0n) {
62
+ return beginCell().storeUint(NFT_COLLECTION_OPCODES.getRoyaltyParams, 32).storeUint(assertQueryId(queryId), 64).endCell();
63
+ }
64
+ var NftCollectionContract = class NftCollectionContract {
65
+ init;
66
+ address;
67
+ constructor(address, init) {
68
+ this.init = init;
69
+ this.address = address;
70
+ }
71
+ static createFromAddress(address) {
72
+ return new NftCollectionContract(address);
73
+ }
74
+ static createFromConfig(config, code, workchain = 0) {
75
+ const init = {
76
+ code,
77
+ data: collectionConfigToCell(config)
78
+ };
79
+ return new NftCollectionContract(contractAddress(workchain, init), init);
80
+ }
81
+ async sendDeploy(provider, via, value) {
82
+ assertTonAmount(value, "NFT deployment value");
83
+ await provider.internal(via, {
84
+ value,
85
+ sendMode: SendMode.PAY_GAS_SEPARATELY,
86
+ body: beginCell().endCell()
87
+ });
88
+ }
89
+ async sendDeployItem(provider, via, item, index, forwardAmount = toNano("0.06"), value = toNano("0.07"), queryId = 0n) {
90
+ assertTonAmount(value, "NFT item deployment value");
91
+ await provider.internal(via, {
92
+ value,
93
+ body: buildNftDeployItemBody(item, index, forwardAmount, queryId),
94
+ sendMode: SendMode.PAY_GAS_SEPARATELY
95
+ });
96
+ }
97
+ async sendChangeOwner(provider, via, newOwner, value = toNano("0.05"), queryId = 0n) {
98
+ assertTonAmount(value, "NFT owner change value");
99
+ await provider.internal(via, {
100
+ value,
101
+ body: buildNftChangeOwnerBody(newOwner, queryId),
102
+ sendMode: SendMode.PAY_GAS_SEPARATELY
103
+ });
104
+ }
105
+ async sendDeployBatch(provider, via, items, value, queryId = 0n) {
106
+ assertTonAmount(value, "NFT batch deployment value");
107
+ await provider.internal(via, {
108
+ value,
109
+ body: buildNftBatchDeployBody(items, queryId),
110
+ sendMode: SendMode.PAY_GAS_SEPARATELY
111
+ });
112
+ }
113
+ async sendGetRoyaltyParams(provider, via, value = toNano("0.05"), queryId = 0n) {
114
+ assertTonAmount(value, "NFT royalty request value");
115
+ await provider.internal(via, {
116
+ value,
117
+ body: buildNftRoyaltyParamsBody(queryId),
118
+ sendMode: SendMode.PAY_GAS_SEPARATELY
119
+ });
120
+ }
121
+ async getNftAddressByIndex(provider, index) {
122
+ const { stack } = await provider.get("get_nft_address_by_index", [{
123
+ type: "int",
124
+ value: assertIndex(index)
125
+ }]);
126
+ return stack.readAddress();
127
+ }
128
+ async getCollectionData(provider) {
129
+ const { stack } = await provider.get("get_collection_data", []);
130
+ return {
131
+ nextItemIndex: stack.readBigNumber(),
132
+ collectionContent: stack.readCell(),
133
+ owner: stack.readAddress()
134
+ };
135
+ }
136
+ async getNftContent(provider, index, content) {
137
+ const { stack } = await provider.get("get_nft_content", [{
138
+ type: "int",
139
+ value: assertIndex(index)
140
+ }, {
141
+ type: "cell",
142
+ cell: content
143
+ }]);
144
+ return stack.readCell();
145
+ }
146
+ };
147
+ //#endregion
148
+ export { NFT_COLLECTION_OPCODES, NftCollectionContract, buildNftBatchDeployBody, buildNftChangeOwnerBody, buildNftDeployItemBody, buildNftRoyaltyParamsBody, collectionConfigToCell };
@@ -0,0 +1,34 @@
1
+ import { Builder, Cell, Slice } from "@ton/core";
2
+ //#region src/nft/content.d.ts
3
+ export declare const NFT_ONCHAIN_CONTENT_KEYS: readonly ["uri", "name", "description", "image", "image_data", "symbol", "decimals", "amount_style", "render_type", "currency", "game"];
4
+ export type NftOnchainContentKey = (typeof NFT_ONCHAIN_CONTENT_KEYS)[number];
5
+ export interface NftContentOffchain {
6
+ readonly type: "offchain";
7
+ readonly uri: string;
8
+ }
9
+ export interface NftContentOnchain {
10
+ readonly type: "onchain";
11
+ readonly data: Partial<Record<NftOnchainContentKey, string>>;
12
+ }
13
+ export type NftContent = NftContentOffchain | NftContentOnchain;
14
+ export interface RoyaltyParameters {
15
+ readonly address: import("@ton/core").Address;
16
+ readonly royaltyFactor: bigint | number;
17
+ readonly royaltyBase: bigint | number;
18
+ }
19
+ export declare function nftContentToCell(content: NftContent): Cell;
20
+ /**
21
+ * Build TEP-64 on-chain metadata for protocol-specific keys.
22
+ *
23
+ * Standard NFT metadata exposes a curated key union above. Some audited
24
+ * protocol contracts add namespaced keys of their own; this helper keeps the
25
+ * same canonical SHA-256 key/value encoding without weakening the standard
26
+ * parser's typed surface.
27
+ */
28
+ export declare function buildOnchainMetadata(data: Readonly<Record<string, string>>): Cell;
29
+ export declare function nftContentFromCell(cell: Cell): NftContent;
30
+ export declare function royaltyParamsToCell(royalty: RoyaltyParameters): Cell;
31
+ export declare function assertCell(value: Cell | unknown, message: string): asserts value is Cell;
32
+ export declare function storeNftContent(builder: Builder, content: NftContent | Cell): Builder;
33
+ export declare function parseNftContentSlice(slice: Slice): NftContent;
34
+ //#endregion
@@ -0,0 +1,142 @@
1
+ import { invariant } from "../core/errors.mjs";
2
+ import { Cell, Dictionary, beginCell } from "@ton/core";
3
+ import { sha256_sync } from "@ton/crypto";
4
+ //#region src/nft/content.ts
5
+ const NFT_ONCHAIN_CONTENT_KEYS = [
6
+ "uri",
7
+ "name",
8
+ "description",
9
+ "image",
10
+ "image_data",
11
+ "symbol",
12
+ "decimals",
13
+ "amount_style",
14
+ "render_type",
15
+ "currency",
16
+ "game"
17
+ ];
18
+ function onchainStringValue() {
19
+ return {
20
+ serialize(value, builder) {
21
+ const bytes = Buffer.from(value, "utf8");
22
+ if (bytes.length <= 126) {
23
+ builder.storeRef(beginCell().storeUint(0, 8).storeBuffer(bytes));
24
+ return;
25
+ }
26
+ const chunkDictionary = Dictionary.empty(Dictionary.Keys.Uint(32), Dictionary.Values.Cell());
27
+ for (const [index, chunk] of splitBytes(bytes, 127).entries()) chunkDictionary.set(index, snakeBytesCell(chunk));
28
+ builder.storeRef(beginCell().storeUint(1, 8).storeDict(chunkDictionary).endCell());
29
+ },
30
+ parse(slice) {
31
+ const value = slice.loadRef().beginParse();
32
+ const tag = value.loadUint(8);
33
+ if (tag === 0) return loadSnakeString(value);
34
+ if (tag === 1) {
35
+ const chunks = Dictionary.load(Dictionary.Keys.Uint(32), Dictionary.Values.Cell(), value);
36
+ return Buffer.concat(chunks.values().map((chunk) => loadSnakeBytesCell(chunk))).toString("utf8");
37
+ }
38
+ throw new Error(`Unsupported on-chain metadata string prefix: ${tag}`);
39
+ }
40
+ };
41
+ }
42
+ function splitBytes(value, chunkSize) {
43
+ const chunks = [];
44
+ for (let offset = 0; offset < value.length; offset += chunkSize) chunks.push(value.subarray(offset, offset + chunkSize));
45
+ return chunks;
46
+ }
47
+ function snakeBytesCell(value) {
48
+ const chunks = splitBytes(value, 127);
49
+ let next;
50
+ for (let index = chunks.length - 1; index >= 1; index -= 1) {
51
+ const chunk = chunks[index];
52
+ if (!chunk) continue;
53
+ const builder = beginCell().storeBuffer(Buffer.from(chunk));
54
+ if (next) builder.storeRef(next);
55
+ next = builder.endCell();
56
+ }
57
+ const builder = beginCell().storeBuffer(Buffer.from(chunks[0] ?? /* @__PURE__ */ new Uint8Array()));
58
+ if (next) builder.storeRef(next);
59
+ return builder.endCell();
60
+ }
61
+ function loadSnakeBytesCell(cell) {
62
+ return loadSnakeBytes(cell.beginParse());
63
+ }
64
+ function loadSnakeString(slice) {
65
+ return loadSnakeBytes(slice).toString("utf8");
66
+ }
67
+ function loadSnakeBytes(slice) {
68
+ const parts = [];
69
+ let current = slice;
70
+ let cellCount = 0;
71
+ while (current) {
72
+ cellCount += 1;
73
+ invariant(cellCount <= 1e4, "INVALID_METADATA", "Metadata snake exceeds the cell limit");
74
+ invariant(current.remainingBits % 8 === 0, "INVALID_METADATA", "Metadata snake contains a partial byte");
75
+ parts.push(current.loadBuffer(current.remainingBits / 8));
76
+ invariant(current.remainingRefs <= 1, "INVALID_METADATA", "Metadata snake contains multiple continuation cells");
77
+ current = current.remainingRefs > 0 ? current.loadRef().beginParse() : void 0;
78
+ }
79
+ return Buffer.concat(parts);
80
+ }
81
+ function nftContentToCell(content) {
82
+ if (content.type === "offchain") {
83
+ const bytes = Buffer.from(content.uri, "utf8");
84
+ const first = bytes.subarray(0, 126);
85
+ const builder = beginCell().storeUint(1, 8).storeBuffer(first);
86
+ if (bytes.length > first.length) builder.storeRef(snakeBytesCell(bytes.subarray(first.length)));
87
+ return builder.endCell();
88
+ }
89
+ const allowedKeys = new Set(NFT_ONCHAIN_CONTENT_KEYS);
90
+ const dictionary = Dictionary.empty(Dictionary.Keys.Buffer(32), onchainStringValue());
91
+ for (const [key, value] of Object.entries(content.data)) if (value !== void 0 && allowedKeys.has(key)) dictionary.set(sha256_sync(key), value);
92
+ return beginCell().storeUint(0, 8).storeDict(dictionary).endCell();
93
+ }
94
+ /**
95
+ * Build TEP-64 on-chain metadata for protocol-specific keys.
96
+ *
97
+ * Standard NFT metadata exposes a curated key union above. Some audited
98
+ * protocol contracts add namespaced keys of their own; this helper keeps the
99
+ * same canonical SHA-256 key/value encoding without weakening the standard
100
+ * parser's typed surface.
101
+ */
102
+ function buildOnchainMetadata(data) {
103
+ const dictionary = Dictionary.empty(Dictionary.Keys.Buffer(32), onchainStringValue());
104
+ for (const [key, value] of Object.entries(data)) dictionary.set(sha256_sync(key), value);
105
+ return beginCell().storeUint(0, 8).storeDict(dictionary).endCell();
106
+ }
107
+ function nftContentFromCell(cell) {
108
+ const slice = cell.beginParse();
109
+ const tag = slice.loadUint(8);
110
+ if (tag === 1) return {
111
+ type: "offchain",
112
+ uri: loadSnakeString(slice)
113
+ };
114
+ if (tag !== 0) throw new Error(`Unsupported NFT metadata content prefix: ${tag}`);
115
+ const dictionary = Dictionary.load(Dictionary.Keys.Buffer(32), onchainStringValue(), slice);
116
+ const keyByHash = new Map(NFT_ONCHAIN_CONTENT_KEYS.map((key) => [Buffer.from(sha256_sync(key)).toString("hex"), key]));
117
+ const data = {};
118
+ for (const [hash, value] of dictionary) {
119
+ const key = keyByHash.get(Buffer.from(hash).toString("hex"));
120
+ if (key) data[key] = value;
121
+ }
122
+ return {
123
+ type: "onchain",
124
+ data
125
+ };
126
+ }
127
+ function royaltyParamsToCell(royalty) {
128
+ invariant(royalty.royaltyFactor >= 0 && royalty.royaltyFactor < 2n ** 16n, "INVALID_TRANSACTION", "NFT royalty factor must fit in 16 bits");
129
+ invariant(royalty.royaltyBase > 0 && royalty.royaltyBase < 2n ** 16n, "INVALID_TRANSACTION", "NFT royalty base must fit in 16 bits and be positive");
130
+ return beginCell().storeUint(royalty.royaltyFactor, 16).storeUint(royalty.royaltyBase, 16).storeAddress(royalty.address).endCell();
131
+ }
132
+ function assertCell(value, message) {
133
+ invariant(value instanceof Cell, "INVALID_METADATA", message);
134
+ }
135
+ function storeNftContent(builder, content) {
136
+ return builder.storeRef(content instanceof Cell ? content : nftContentToCell(content));
137
+ }
138
+ function parseNftContentSlice(slice) {
139
+ return nftContentFromCell(slice.loadRef());
140
+ }
141
+ //#endregion
142
+ export { NFT_ONCHAIN_CONTENT_KEYS, assertCell, buildOnchainMetadata, nftContentFromCell, nftContentToCell, parseNftContentSlice, royaltyParamsToCell, storeNftContent };
@@ -0,0 +1,35 @@
1
+ import { NFT_ONCHAIN_CONTENT_KEYS, NftContent, NftContentOffchain, NftContentOnchain, NftOnchainContentKey, RoyaltyParameters, assertCell, buildOnchainMetadata, nftContentFromCell, nftContentToCell, parseNftContentSlice, royaltyParamsToCell, storeNftContent } from "./content.mjs";
2
+ import { NFT_COLLECTION_OPCODES, NewNftItem, NftCollectionConfig, NftCollectionContract, NftCollectionData, buildNftBatchDeployBody, buildNftChangeOwnerBody, buildNftDeployItemBody, buildNftRoyaltyParamsBody, collectionConfigToCell } from "./collection.mjs";
3
+ import { NFT_IMPLEMENTATION_PROFILES, NftCollectionImplementationVersion, NftImplementationProfile, NftItemImplementationVersion } from "./versions.mjs";
4
+ import { Address, Cell, ContractProvider, Sender } from "@ton/core";
5
+ //#region src/nft/index.d.ts
6
+ export declare const NFT_OPCODES: {
7
+ readonly transfer: 1607220500;
8
+ readonly ownershipAssigned: 85167505;
9
+ readonly getStaticData: 801842850;
10
+ };
11
+ export interface NftTransferInput {
12
+ readonly newOwner: Address;
13
+ readonly responseDestination: Address;
14
+ readonly queryId?: bigint;
15
+ readonly forwardAmount?: bigint;
16
+ readonly customPayload?: Cell;
17
+ readonly forwardPayload?: Cell;
18
+ }
19
+ export interface NftItemData {
20
+ readonly initialized: boolean;
21
+ readonly index: bigint;
22
+ readonly collection: Address;
23
+ readonly owner: Address | null;
24
+ readonly content: Cell | null;
25
+ }
26
+ export declare class NftItemContract {
27
+ readonly address: Address;
28
+ private constructor();
29
+ static create(address: Address): NftItemContract;
30
+ getData(provider: ContractProvider): Promise<NftItemData>;
31
+ sendTransfer(provider: ContractProvider, via: Sender, input: NftTransferInput, value: bigint): Promise<void>;
32
+ }
33
+ export declare function buildNftTransferBody(input: NftTransferInput): Cell;
34
+ //#endregion
35
+ export { NFT_COLLECTION_OPCODES, NFT_IMPLEMENTATION_PROFILES, NFT_ONCHAIN_CONTENT_KEYS, NewNftItem, NftCollectionConfig, NftCollectionContract, NftCollectionData, NftCollectionImplementationVersion, NftContent, NftContentOffchain, NftContentOnchain, NftImplementationProfile, NftItemImplementationVersion, NftOnchainContentKey, RoyaltyParameters, assertCell, buildNftBatchDeployBody, buildNftChangeOwnerBody, buildNftDeployItemBody, buildNftRoyaltyParamsBody, buildOnchainMetadata, collectionConfigToCell, nftContentFromCell, nftContentToCell, parseNftContentSlice, royaltyParamsToCell, storeNftContent };