Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/toncenter/tonweb into van…
Browse files Browse the repository at this point in the history
…illa-tests-for-ts
  • Loading branch information
slavafomin committed Mar 15, 2022
2 parents 79f046f + ebc156c commit 0208f96
Show file tree
Hide file tree
Showing 15 changed files with 711 additions and 292 deletions.
2 changes: 1 addition & 1 deletion dist/tonweb.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions dist/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { LogFunction, } from './providers/block-subscription/in-memory-block-sto
export { ShardBlock, BlockStorage, } from './providers/block-subscription/block-storage';
import { Address, AddressType } from './utils/Address';
export { AddressType } from './utils/Address';
import { ParsedTransferUrl } from './utils/common';
import { BitString } from './boc/bit-string';
import { Cell } from './boc/cell';
import { Contract } from './contract/contract';
Expand Down Expand Up @@ -59,6 +60,8 @@ export default class TonWeb {
stringToBase64(str: string): string;
base64ToBytes(base64: string): Uint8Array;
readNBytesUIntFromArray(n: number, ui8array: Uint8Array): number;
parseTransferUrl(url: string): ParsedTransferUrl;
formatTransferUrl(address: string, amount?: string, text?: string): string;
};
static Address: typeof Address;
static boc: {
Expand Down Expand Up @@ -120,6 +123,8 @@ export default class TonWeb {
stringToBase64(str: string): string;
base64ToBytes(base64: string): Uint8Array;
readNBytesUIntFromArray(n: number, ui8array: Uint8Array): number;
parseTransferUrl(url: string): ParsedTransferUrl;
formatTransferUrl(address: string, amount?: string, text?: string): string;
};
Address: typeof Address;
boc: {
Expand Down
9 changes: 9 additions & 0 deletions dist/types/utils/common.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ export declare function base64toString(base64: string): string;
export declare function stringToBase64(str: string): string;
export declare function base64ToBytes(base64: string): Uint8Array;
export declare function readNBytesUIntFromArray(n: number, ui8array: Uint8Array): number;

export declare interface ParsedTransferUrl {
address: string;
amount?: string;
text?: string
}

export declare function parseTransferUrl(url: string): ParsedTransferUrl;
export declare function formatTransferUrl(address: string, amount?: string, text?: string): string;
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tonweb",
"version": "0.0.34",
"version": "0.0.35",
"description": "TonWeb - JavaScript API for TON blockchain",
"main": "src/index.js",
"types": "dist/types/index.d.ts",
Expand Down
64 changes: 63 additions & 1 deletion src/contract/token/ft/JettonMinter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,66 @@
const {Contract} = require("../../index");
const {Cell} = require("../../../boc");
const {createOffchainUriCell, parseOffchainUriCell, parseAddress} = require("../nft/NftUtils");

/**
* ATTENTION: this is DRAFT, there will be changes
*/
class JettonMinter extends Contract {
}

/**
* @param provider
* @param options {{adminAddress: Address, jettonContentUri: string, jettonWalletCodeHex: string, address?: Address | string, code?: Cell}}
*/
constructor(provider, options) {
options.wc = 0;
options.code = options.code || Cell.oneFromBoc('B5EE9C7241020701000133000114FF00F4A413F4BCF2C80B0102016202030202CD0405001FA13C5BDA89A1F401F481A9A860FEAA4101C1D1910E38048ADF068698180B8D848ADF07D201800E98FE99FF6A2687D007D206A6A18400AA9385D47149B28B0E382F97024817D007D207D00182A0900AA2383F803AC502099E428027D012C678B666664F6AA701AC0090B5D71812F834207F97840600A5F7C142281B82A1009AA0A01E428027D012C678B00E78B666491646580897A007A00658064907C80383A6465816503E5FFE4E840073B400C646582A801E78B28037D0165B5E609E58F89659F80FD0164B87D804009E02FA00FA4030F8282570542013541403C85004FA0258CF1601CF16CCC922C8CB0112F400F400CB00C9F9007074C8CB02CA07CBFFC9D05006C705F2E2C35004A15520C85004FA0258CF16CCCCC9ED549C3AF745');
super(provider, options);
}

/**
* @override
* @private
* @return {Cell} cell contains jetton minter data
*/
createDataCell() {
const cell = new Cell();
cell.bits.writeCoins(0); // total supply
cell.bits.writeAddress(this.options.adminAddress);
cell.refs[0] = createOffchainUriCell(this.options.jettonContentUri);
cell.refs[1] = Cell.oneFromBoc(this.options.jettonWalletCodeHex);
return cell;
}

/**
* params {{tokenAmount: BN, destination: Address, amount: BN, queryId?: number}}
* @return {Cell}
*/
createMintBody(params) {
const body = new Cell();
body.bits.writeUint(21, 32); // OP mint
body.bits.writeUint(params.queryId || 0, 64); // query_id
body.bits.writeCoins(params.tokenAmount);
body.bits.writeAddress(params.destination);
body.bits.writeCoins(params.amount);
return body;
}

/**
* @return {Promise<{ totalSupply: BN, isMutable: boolean, adminAddress: Address|null, jettonContentUri: string, tokenWalletCode: Cell }>}
*/
async getJettonData() {
const myAddress = await this.getAddress();
const result = await this.provider.call2(myAddress.toString(), 'get_jetton_data');

const totalSupply = result[0];
const isMutable = result[1].toNumber() === -1;
const adminAddress = parseAddress(result[2]);
const jettonContentUri = parseOffchainUriCell(result[3]);
const tokenWalletCode = result[4];

return {totalSupply, isMutable, adminAddress, jettonContentUri, tokenWalletCode};
}

}

module.exports = {JettonMinter};
66 changes: 65 additions & 1 deletion src/contract/token/ft/JettonWallet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,68 @@
const {Contract} = require("../../index");
const {Cell} = require("../../../boc");
const {parseAddress} = require("../nft/NftUtils");
const {BN} = require("../../../utils");

const JETTON_WALLET_CODE_HEX = 'B5EE9C72410216010002CB000114FF00F4A413F4BCF2C80B0102016202030202CC04050009A0F605E00D02012006070201480E0F02F7D00E8698180B8D84A1818F805F07D207D2018FD0018B8EB90FD0018FD001801698FC00729105D471918B6117803290B6382F9716081E99FFD001809D0400838400864658293678B10FD0165B5658F89E59FE4C0207D802001F803F04005A9105D4A98A099F804704006A9105D4A989998F804F04008895D71812F82408090201200A0B00084133F00A0008840FF2F000115FA443070BAF2E14D80201200C0D00173B51343E803E903E90350C20001F3214013E809633C58073C5B3327B55200201201011020120141501F700F4CFFE803E90087C017C01944DA8548AB1C17CB8B04A30BFFCB8B0950D109C150804D50500F214013E809633C58073C5B33248B232C044BD003D0032C032483E401C1D3232C0B281F2FFF274013E90087C017D010C7E801DE0063232C1540233C59C3E8085F2DAC4F320037232C7C672CFD401FE8088B3C59401A01201F33C018174CFFE80145468017E903E90151C965C150804D50500F214013E809633C58073C5B33248B232C044BD003D0032C0327E401C1D3232C0B281F2FFF274140271C17CB8B0C1FE80086497C138C360822625A01CBEC0A0041C20043232C15401F3C589BE8085B2DA8572C7C532CFF2604020BEC01000FC01E013005ECF1625FA025003CF16C95005CC07AA0013A08208989680AA008208989680A0A014BCF2E2C504C98040FB001023F007005A718018C8CB0528CF165003FA0212CB6A800CC8CB1F5250CB3F5004FA0225CF1658CF1601CF16C901CCC971FB0000A73C0181F4CFFE803E900C145468549271C17CB8B049F0BFFCB8B0A0822625A02A8005A805AF3CB8B0E004B232C7C572CFD400FE8088B3C58073C5B25C60043232C14933C59C3E80B2DAB33260103EC01004FC01E00047200835C87C018134C7E00354882EA00484EE84AC7CB8B174CFCC7E800C04E81408FC01E0387A65F0';

/**
* ATTENTION: this is DRAFT, there will be changes
*/
class JettonWallet extends Contract {
}
/**
* @param provider
* @param options {{address?: Address | string, code?: Cell}}
*/
constructor(provider, options) {
options.wc = 0;
options.code = options.code || Cell.oneFromBoc(JETTON_WALLET_CODE_HEX);
super(provider, options);
}

/**
* @param params {{queryId?: number, tokenAmount: BN, toAddress: Address, responseAddress: Address, forwardAmount: BN, forwardPayload: Uint8Array}}
*/
async createTransferBody(params) {
const cell = new Cell();
cell.bits.writeUint(11, 32); // request_transfer op
cell.bits.writeUint(params.queryId || 0, 64);
cell.bits.writeCoins(params.tokenAmount);
cell.bits.writeAddress(params.toAddress);
cell.bits.writeAddress(params.responseAddress);
cell.bits.writeBit(false); // null custom_payload
cell.bits.writeCoins(params.forwardAmount || new BN(0));
cell.bits.writeBit(false); // forward_payload in this slice, not separate cell
if (params.forwardPayload) {
cell.bits.writeBytes(params.forwardPayload);
}
return cell;
}

/**
* @param params {{queryId?: number, tokenAmount: BN, responseAddress: Address}}
*/
async createBurnBody(params) {
const cell = new Cell();
cell.bits.writeUint(17, 32); // burn op
cell.bits.writeUint(params.queryId || 0, 64);
cell.bits.writeCoins(params.tokenAmount);
cell.bits.writeAddress(params.responseAddress);
return cell;
}

async getData() {
const myAddress = await this.getAddress();
const result = await this.provider.call2(myAddress.toString(), 'get_wallet_data');

const balance = result[0];
const ownerAddress = parseAddress(result[1]);
const jettonMinterAddress = parseAddress(result[2]);
const tokenWalletCode = result[3];

return {balance, ownerAddress, jettonMinterAddress, tokenWalletCode};
}
}

JettonWallet.codeHex = JETTON_WALLET_CODE_HEX;

module.exports = {JettonWallet};
2 changes: 1 addition & 1 deletion src/contract/token/nft/NftCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {createOffchainUriCell, serializeUri, parseOffchainUriCell} = require("./N
class NftCollection extends Contract {
/**
* @param provider
* @param options {{ownerAddress: Address, collectionContentUri: string, nftItemContentBaseUri: string, nftItemCodeHex: string, royalty: number, royaltyAddress: Address, address?: Address | string, cell?: Cell}}
* @param options {{ownerAddress: Address, collectionContentUri: string, nftItemContentBaseUri: string, nftItemCodeHex: string, royalty: number, royaltyAddress: Address, address?: Address | string, code?: Cell}}
*/
constructor(provider, options) {
options.wc = 0;
Expand Down
5 changes: 2 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const utils = require("./utils");
const Address = require("./utils/Address").default;
utils.Address = Address;
const Address = utils.Address;
const boc = require("./boc");
const AppTon = require("./ledger/AppTon");
const HttpProvider = require("./providers").default;
Expand All @@ -14,7 +13,7 @@ const {SubscriptionContract} = require("./contract/subscription/index");
const TransportWebUSB = require("@ledgerhq/hw-transport-webusb").default;
const TransportWebHID = require("@ledgerhq/hw-transport-webhid").default;
const BluetoothTransport = require("@ledgerhq/hw-transport-web-ble").default;
const version = '0.0.33';
const version = '0.0.35';

class TonWeb {
constructor(provider) {
Expand Down
137 changes: 137 additions & 0 deletions src/test-jetton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
const TonWeb = require("./index");
const {JettonMinter, JettonWallet} = TonWeb.token.jetton;

const init = async () => {
const tonweb = new TonWeb(new TonWeb.HttpProvider('https://testnet.toncenter.com/api/v2/jsonRPC'));

const seed = TonWeb.utils.base64ToBytes('vt58J2v6FaSuXFGcyGtqT5elpVxcZ+I1zgu/GUfA5uY=');
const seed2 = TonWeb.utils.base64ToBytes('at58J2v6FaSuXFGcyGtqT5elpVxcZ+I1zgu/GUfA5uY=');
const WALLET2_ADDRESS = 'EQB6-6po0yspb68p7RRetC-hONAz-JwxG9514IEOKw_llXd5';
const keyPair = TonWeb.utils.nacl.sign.keyPair.fromSeed(seed);
const WalletClass = tonweb.wallet.all['v3R1'];
const wallet = new WalletClass(tonweb.provider, {
publicKey: keyPair.publicKey,
wc: 0
});
const walletAddress = await wallet.getAddress();
console.log('wallet address=', walletAddress.toString(true, true, true));

const minter = new JettonMinter(tonweb.provider, {
adminAddress: walletAddress,
jettonContentUri: 'http://localhost/nft-marketplace/my_collection.json',
jettonWalletCodeHex: JettonWallet.codeHex
});
const minterAddress = await minter.getAddress();
console.log('minter address=', minterAddress.toString(true, true, true));

const deployMinter = async () => {
const seqno = (await wallet.methods.seqno().call()) || 0;
console.log({seqno})

console.log(
await wallet.methods.transfer({
secretKey: keyPair.secretKey,
toAddress: minterAddress.toString(true, true, true),
amount: TonWeb.utils.toNano(0.5),
seqno: seqno,
payload: null, // body
sendMode: 3,
stateInit: (await minter.createStateInit()).stateInit
}).send()
);
}

const getMinterInfo = async () => {
const data = await minter.getJettonData();
data.totalSupply = data.totalSupply.toString();
data.adminAddress = data.adminAddress.toString(true, true, true);
console.log(data);
}

const mint = async () => {
const seqno = (await wallet.methods.seqno().call()) || 0;
console.log({seqno})

console.log(
await wallet.methods.transfer({
secretKey: keyPair.secretKey,
toAddress: minterAddress.toString(true, true, true),
amount: TonWeb.utils.toNano('0.05'),
seqno: seqno,
payload: await minter.createMintBody({
tokenAmount: TonWeb.utils.toNano(100500),
destination: walletAddress,
amount: TonWeb.utils.toNano('0.04')
}),
sendMode: 3,
}).send()
);
}

const JETTON_WALLET_ADDRESS = 'EQBIIxndZHvxYR9vYxxf6T_V207wstz_a0MsD3Edf1ssstn0';
// const JETTON_WALLET_ADDRESS = 'EQAFeJKruIRXk25m_jfCGSYu2v7wJHvJx12N0r3D9dnp_1Gq';
console.log('jettonWalletAddress=', JETTON_WALLET_ADDRESS);

const jettonWallet = new JettonWallet(tonweb.provider, {
address: JETTON_WALLET_ADDRESS
});

const getJettonWalletInfo = async () => {
const data = await jettonWallet.getData();
data.balance = data.balance.toString();
data.ownerAddress = data.ownerAddress.toString(true, true, true);
data.jettonMinterAddress = data.jettonMinterAddress.toString(true, true, true);
console.log(data);
}

const transfer = async () => {
const seqno = (await wallet.methods.seqno().call()) || 0;
console.log({seqno})

console.log(
await wallet.methods.transfer({
secretKey: keyPair.secretKey,
toAddress: JETTON_WALLET_ADDRESS,
amount: TonWeb.utils.toNano(0.4),
seqno: seqno,
payload: await jettonWallet.createTransferBody({
tokenAmount: TonWeb.utils.toNano('500'),
toAddress: new TonWeb.utils.Address(WALLET2_ADDRESS),
forwardAmount: TonWeb.utils.toNano(0.1),
forwardPayload: new TextEncoder().encode('gift'),
responseAddress: walletAddress
}),
sendMode: 3,
}).send()
);
}


const burn = async () => {
const seqno = (await wallet.methods.seqno().call()) || 0;
console.log({seqno})

console.log(
await wallet.methods.transfer({
secretKey: keyPair.secretKey,
toAddress: JETTON_WALLET_ADDRESS,
amount: TonWeb.utils.toNano(0.4),
seqno: seqno,
payload: await jettonWallet.createBurnBody({
tokenAmount: TonWeb.utils.toNano('400'),
responseAddress: walletAddress
}),
sendMode: 3,
}).send()
);
}

// await deployMinter();
// await getMinterInfo();
// await mint();
// await getJettonWalletInfo();
// await transfer();
// await burn();
}

init();
2 changes: 1 addition & 1 deletion src/test-nft.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async function init() {
console.log(
await wallet.methods.transfer({
secretKey: keyPair.secretKey,
toAddress: nftCollectionAddress.toString(true, true, false), // non-bounceable
toAddress: nftCollectionAddress.toString(true, true, true),
amount: TonWeb.utils.toNano(1),
seqno: seqno,
payload: null, // body
Expand Down
16 changes: 16 additions & 0 deletions src/test-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const TonWeb = require("./index");

console.log(TonWeb.utils.formatTransferUrl('EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG'))
console.log(TonWeb.utils.formatTransferUrl('EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG', '12300000000'))
console.log(TonWeb.utils.formatTransferUrl('EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG', '12300000000', 'hello'))
console.log(TonWeb.utils.formatTransferUrl('EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG', '12300000000', 'https://ton.org'))
console.log(TonWeb.utils.formatTransferUrl('EQBvI0aFLnw2QbZgjMPCLRdtRHxhUyinQudg6sdiohIwg5jL', undefined, ' ?&'))

console.log(TonWeb.utils.parseTransferUrl('ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG'));
console.log(TonWeb.utils.parseTransferUrl('ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG?amount=12300000000'));
console.log(TonWeb.utils.parseTransferUrl('ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG?amount=12300000000&text=hello'));
console.log(TonWeb.utils.parseTransferUrl('ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG?amount=12300000000&text=https%3A%2F%2Fton.org'));
console.log(TonWeb.utils.parseTransferUrl('ton://transfer/EQBvI0aFLnw2QbZgjMPCLRdtRHxhUyinQudg6sdiohIwg5jL?text=%20%3F%26'));
console.log(TonWeb.utils.parseTransferUrl('ton://transfer/EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG?amount=123.3'));


2 changes: 1 addition & 1 deletion src/utils/Address.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {crc16, hexToBytes, bytesToHex, stringToBytes, base64toString, stringToBase64} = require("./index");
const {crc16, hexToBytes, bytesToHex, stringToBytes, base64toString, stringToBase64} = require("./Utils");

const bounceable_tag = 0x11;
const non_bounceable_tag = 0x51;
Expand Down
Loading

0 comments on commit 0208f96

Please sign in to comment.