Comparing version 1.1.1 to 1.2.0
/// <reference types="node" /> | ||
import BN from 'bn.js'; | ||
import { Address } from '../address/Address'; | ||
export declare class BitString implements Iterable<boolean> { | ||
@@ -24,4 +25,6 @@ #private; | ||
writeGrams(amount: number | BN): void; | ||
writeAddress(address: Address | null): void; | ||
writeBitString(value: BitString): void; | ||
clone(): BitString; | ||
toString(): string; | ||
} |
@@ -146,2 +146,13 @@ "use strict"; | ||
} | ||
writeAddress(address) { | ||
if (address === null) { | ||
this.writeUint(0, 2); | ||
} | ||
else { | ||
this.writeUint(2, 2); | ||
this.writeUint(0, 1); | ||
this.writeInt(address.workChain, 8); | ||
this.writeBuffer(address.hash); | ||
} | ||
} | ||
writeBitString(value) { | ||
@@ -155,2 +166,14 @@ for (let v of value) { | ||
} | ||
toString() { | ||
let res = ''; | ||
for (let v of this) { | ||
if (v) { | ||
res = res + '1'; | ||
} | ||
else { | ||
res = res + '0'; | ||
} | ||
} | ||
return res; | ||
} | ||
// | ||
@@ -157,0 +180,0 @@ // Helpers |
/// <reference types="node" /> | ||
import { TonWallet } from "./TonWallet"; | ||
import { Address } from "../address/Address"; | ||
import { Message } from "../messages/Message"; | ||
export declare type TonClientParameters = { | ||
@@ -16,4 +17,28 @@ endpoint: string; | ||
*/ | ||
getBalance(address: string | Address): Promise<number>; | ||
getBalance(address: Address): Promise<number>; | ||
/** | ||
* Invoke get method | ||
* @param address contract address | ||
* @param name name of method | ||
* @param params optional parameters | ||
* @returns stack and gas_used field | ||
*/ | ||
callGetMethod(address: Address, name: string, params?: any[]): Promise<{ | ||
gas_used: number; | ||
stack: any[]; | ||
}>; | ||
/** | ||
* Send message to a network | ||
* @param src source message | ||
*/ | ||
sendMessage(src: Message): Promise<void>; | ||
/** | ||
* Resolves contract state | ||
* @param address contract address | ||
*/ | ||
getContractState(address: Address): Promise<{ | ||
balance: number; | ||
state: "frozen" | "active" | "uninitialized"; | ||
}>; | ||
/** | ||
* Open Wallet | ||
@@ -20,0 +45,0 @@ * @param publicKey wallet public key |
@@ -6,2 +6,5 @@ "use strict"; | ||
const ton_crypto_1 = require("ton-crypto"); | ||
const Address_1 = require("../address/Address"); | ||
const Cell_1 = require("../boc/Cell"); | ||
const convert_1 = require("../utils/convert"); | ||
const TonWeb = require('tonweb'); | ||
@@ -20,11 +23,50 @@ class TonClient { | ||
*/ | ||
getBalance(address) { | ||
async getBalance(address) { | ||
let balance; | ||
if (typeof address === 'string') { | ||
return this.#client.getBalance(address); | ||
balance = await this.#client.getBalance(address); | ||
} | ||
else { | ||
return this.#client.getBalance(address.toString()); | ||
balance = await this.#client.getBalance(address.toString()); | ||
} | ||
return (0, convert_1.fromNano)(balance); | ||
} | ||
/** | ||
* Invoke get method | ||
* @param address contract address | ||
* @param name name of method | ||
* @param params optional parameters | ||
* @returns stack and gas_used field | ||
*/ | ||
async callGetMethod(address, name, params = []) { | ||
let res = await this.#client.provider.call(address.toString(), name, params); | ||
if (res.exit_code !== 0) { | ||
throw Error('Unable to execute get method'); | ||
} | ||
return { gas_used: res.gas_used, stack: res.stack }; | ||
} | ||
/** | ||
* Send message to a network | ||
* @param src source message | ||
*/ | ||
async sendMessage(src) { | ||
const cell = new Cell_1.Cell(); | ||
src.writeTo(cell); | ||
let base64Boc = (await cell.toBoc({ idx: false })).toString('base64'); | ||
await this.#client.provider.sendBoc(base64Boc); | ||
} | ||
/** | ||
* Resolves contract state | ||
* @param address contract address | ||
*/ | ||
async getContractState(address) { | ||
let info = await this.#client.provider.getAddressInfo(address.toString()); | ||
let balance = (0, convert_1.fromNano)(info.balance); | ||
let state = info.state; | ||
return { | ||
balance, | ||
state | ||
}; | ||
} | ||
/** | ||
* Open Wallet | ||
@@ -38,3 +80,3 @@ * @param publicKey wallet public key | ||
}); | ||
const address = (await walletContract.getAddress()).toString(true, true, true); | ||
const address = Address_1.Address.parseRaw((await walletContract.getAddress()).toString(false)); | ||
return new TonWallet_1.TonWallet(this, address, walletContract); | ||
@@ -41,0 +83,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ton_crypto_1 = require("ton-crypto"); | ||
const Address_1 = require("../address/Address"); | ||
const createTestClient_1 = require("../tests/createTestClient"); | ||
const TonClient_1 = require("./TonClient"); | ||
@@ -8,7 +10,39 @@ describe('TonClient', () => { | ||
const client = new TonClient_1.TonClient({ endpoint: 'https://toncenter.com/api/v2/jsonRPC' }); | ||
let balance = await client.getBalance('0QAs9VlT6S776tq3unJcP5Ogsj-ELLunLXuOb1EKcOQi4-QO'); | ||
const address = Address_1.Address.parseFriendly('0QAs9VlT6S776tq3unJcP5Ogsj-ELLunLXuOb1EKcOQi4-QO'); | ||
let balance = (await client.getBalance(address.address)); | ||
expect(balance).toBe(0); | ||
balance = await client.getBalance(Address_1.Address.parseFriendly('0QAs9VlT6S776tq3unJcP5Ogsj-ELLunLXuOb1EKcOQi4-QO').address); | ||
balance = (await client.getBalance(Address_1.Address.parseFriendly('0QAs9VlT6S776tq3unJcP5Ogsj-ELLunLXuOb1EKcOQi4-QO').address)); | ||
expect(balance).toBe(0); | ||
}); | ||
it('should use workchain 0 when load from mnemonics', async () => { | ||
const client = await (0, createTestClient_1.createTestClient)(); | ||
const mnemonics = [ | ||
'circle', 'task', 'moral', | ||
'disagree', 'echo', 'kingdom', | ||
'agent', 'kite', 'love', | ||
'indoor', 'manage', 'orphan', | ||
'royal', 'business', 'whisper', | ||
'saddle', 'sun', 'dog', | ||
'street', 'cart', 'flash', | ||
'cheese', 'swift', 'turkey' | ||
]; | ||
const key = await (0, ton_crypto_1.mnemonicToWalletKey)(mnemonics); | ||
let wallet = await client.openWallet(key.publicKey); | ||
expect(wallet.address.workChain).toBe(0); | ||
expect(wallet.address.hash).toEqual(Buffer.from('d1e27790cea91f133d2847785705c26987ae1de4d75d3fc1fcc1f374b6140802', 'hex')); | ||
}); | ||
it('should use workchain 0 when creating new wallet', async () => { | ||
const client = await (0, createTestClient_1.createTestClient)(); | ||
let wallet = await client.createWallet(); | ||
expect(wallet.wallet.address.workChain).toBe(0); | ||
}); | ||
it('should resolve contract info', async () => { | ||
const client = await (0, createTestClient_1.createTestClient)(); | ||
let state = await client.getContractState(Address_1.Address.parseFriendly('0QCyt4ltzak71h6XkyK4ePfZCzJQDSVUNuvZ3VE7hP_Q-GTE').address); | ||
expect(state.balance).toBe(0); | ||
expect(state.state).toBe('uninitialized'); | ||
state = await client.getContractState(Address_1.Address.parseFriendly('EQDR4neQzqkfEz0oR3hXBcJph64d5NddP8H8wfN0thQIAqDH').address); | ||
expect(state.balance).toBeGreaterThan(0); | ||
expect(state.state).toBe('active'); | ||
}); | ||
}); |
/// <reference types="node" /> | ||
import BN from "bn.js"; | ||
import { Address } from ".."; | ||
import { Cell } from "../boc/Cell"; | ||
import { Maybe } from "../types"; | ||
import { TonClient } from "./TonClient"; | ||
declare type TransferPackage = { | ||
to: Address; | ||
value: BN; | ||
seqno: number; | ||
bounceable: boolean; | ||
sendMode: number; | ||
}; | ||
export declare class TonWallet { | ||
#private; | ||
readonly address: string; | ||
constructor(client: TonClient, address: string, contract: any); | ||
readonly address: Address; | ||
constructor(client: TonClient, address: Address, contract: any); | ||
/** | ||
@@ -25,7 +36,21 @@ * Returns balance of wallet | ||
transfer: (args: { | ||
to: string; | ||
amount: number; | ||
to: Address; | ||
value: number; | ||
seqno: number; | ||
secretKey: Buffer; | ||
bounceable?: Maybe<boolean>; | ||
}) => Promise<void>; | ||
/** | ||
* Prepares transfer | ||
* @param args | ||
*/ | ||
prepareTransfer: (args: { | ||
to: Address; | ||
value: number; | ||
seqno?: Maybe<number>; | ||
bounceable?: Maybe<boolean>; | ||
}) => Promise<TransferPackage>; | ||
signTransfer: (src: TransferPackage, secretKey: Buffer) => Promise<Cell>; | ||
sendTransfer: (signed: Cell) => Promise<void>; | ||
} | ||
export {}; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TonWallet = void 0; | ||
const TonWeb = require('tonweb'); | ||
const Cell_1 = require("../boc/Cell"); | ||
const CommonMessageInfo_1 = require("../messages/CommonMessageInfo"); | ||
const EmptyMessage_1 = require("../messages/EmptyMessage"); | ||
const InternalMessage_1 = require("../messages/InternalMessage"); | ||
const WalletV3SigningMessage_1 = require("../messages/wallet/WalletV3SigningMessage"); | ||
const convert_1 = require("../utils/convert"); | ||
const tweetnacl_1 = __importDefault(require("tweetnacl")); | ||
const ExternalMessage_1 = require("../messages/ExternalMessage"); | ||
const RawMessage_1 = require("../messages/RawMessage"); | ||
class TonWallet { | ||
@@ -26,3 +37,4 @@ address; | ||
async getSeqNo() { | ||
return await this.#contract.methods.seqno().call(); | ||
let res = await this.#client.callGetMethod(this.address, 'seqno'); | ||
return parseInt(res.stack[0][1], 16); | ||
} | ||
@@ -39,13 +51,82 @@ /** | ||
transfer = async (args) => { | ||
// Create Transfer | ||
const transfer = this.#contract.methods.transfer({ | ||
secretKey: args.secretKey, | ||
toAddress: args.to, | ||
amount: TonWeb.utils.toNano(args.amount), | ||
// Prepare transaction | ||
let prepare = await this.prepareTransfer({ | ||
to: args.to, | ||
value: args.value, | ||
seqno: args.seqno, | ||
sendMode: 3 /* Some magic number */ | ||
bounceable: args.bounceable | ||
}); | ||
await transfer.send(); | ||
// Sign transfer | ||
let signed = await this.signTransfer(prepare, args.secretKey); | ||
// Send transfer | ||
await this.sendTransfer(signed); | ||
}; | ||
/** | ||
* Prepares transfer | ||
* @param args | ||
*/ | ||
prepareTransfer = async (args) => { | ||
// Resolve bounceable | ||
let seqno; | ||
if (args.seqno !== null && args.seqno !== undefined) { | ||
seqno = args.seqno; | ||
} | ||
else { | ||
seqno = await this.getSeqNo(); | ||
} | ||
// Resolve bounceable | ||
let bounceable; | ||
if (args.bounceable !== null && args.bounceable !== undefined) { | ||
bounceable = args.bounceable; | ||
} | ||
else { | ||
let state = await this.#client.getContractState(args.to); | ||
if (state.state === 'uninitialized') { | ||
bounceable = false; | ||
} | ||
else { | ||
bounceable = true; | ||
} | ||
} | ||
// Prepared package | ||
return { | ||
to: args.to, | ||
seqno, | ||
bounceable, | ||
value: (0, convert_1.toNano)(args.value), | ||
sendMode: 3 | ||
}; | ||
}; | ||
signTransfer = async (src, secretKey) => { | ||
// Signinig message | ||
const signingMessage = new WalletV3SigningMessage_1.WalletV3SigningMessage({ | ||
seqno: src.seqno, | ||
sendMode: src.sendMode, | ||
order: new InternalMessage_1.InternalMessage({ | ||
to: src.to, | ||
value: src.value, | ||
bounce: src.bounceable, | ||
body: new CommonMessageInfo_1.CommonMessageInfo({ body: new EmptyMessage_1.EmptyMessage() }) | ||
}) | ||
}); | ||
// Resolve signature | ||
const cell = new Cell_1.Cell(); | ||
signingMessage.writeTo(cell); | ||
let signature = Buffer.from(tweetnacl_1.default.sign.detached(new Uint8Array(await cell.hash()), new Uint8Array(secretKey))); | ||
// Resolve body | ||
const body = new Cell_1.Cell(); | ||
body.bits.writeBuffer(Buffer.from(signature)); | ||
signingMessage.writeTo(body); | ||
return body; | ||
}; | ||
sendTransfer = async (signed) => { | ||
const message = new ExternalMessage_1.ExternalMessage({ | ||
to: this.address, | ||
body: new CommonMessageInfo_1.CommonMessageInfo({ | ||
body: new RawMessage_1.RawMessage(signed) | ||
}) | ||
}); | ||
await this.#client.sendMessage(message); | ||
}; | ||
} | ||
exports.TonWallet = TonWallet; |
{ | ||
"name": "ton", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"repository": "https://github.com/ex3ndr/ton.git", | ||
@@ -13,4 +13,4 @@ "author": "Steve Korshakov <steve@korshakov.com>", | ||
"build": "rm -fr build && tsc --declaration", | ||
"test": "jest && karma start --single-run", | ||
"release": "yarn build && yarn publish" | ||
"test": "jest --runInBand", | ||
"release": "yarn build && yarn test && yarn publish" | ||
}, | ||
@@ -17,0 +17,0 @@ "devDependencies": { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
62325
65
1689
1