PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/tonweb/src/contract/wallet
Просмотр файла: WalletContract.js
const {Contract} = require("../index.js");
const {Cell} = require("../../boc");
const {nacl, stringToBytes, Address, BN} = require("../../utils");
/**
* Abstract standard wallet class
*/
class WalletContract extends Contract {
/**
* @param provider {HttpProvider}
* @param options? {{code: Cell, publicKey?: Uint8Array, address?: Address | string, wc?: number}}
*/
constructor(provider, options) {
if (!options.publicKey && !options.address) throw new Error('WalletContract required publicKey or address in options')
super(provider, options);
this.methods = {
/**
* @param params {{secretKey: Uint8Array, seqno: number, expireAt?: number, toAddress: Address | string, amount: BN, payload?: string | Uint8Array | Cell, sendMode?: number, stateInit?: Cell }}
*/
transfer: (params) => Contract.createMethod(provider, this.createTransferMessage(params.secretKey, params.toAddress, params.amount, params.seqno, params.payload, params.sendMode, !Boolean(params.secretKey), params.stateInit, params.expireAt)),
/**
* @param params {{secretKey: Uint8Array, seqno: number, expireAt?: number, messages: [{toAddress: Address | string, amount: BN, payload?: string | Uint8Array | Cell, sendMode?: number, stateInit?: Cell }]}}
*/
transfers: (params) => Contract.createMethod(provider, this.createTransferMessages(params.secretKey, params.seqno, params.messages, !Boolean(params.secretKey), params.expireAt)),
seqno: () => {
return {
/**
* @return {Promise<number|null>}
*/
call: async () => {
const address = await this.getAddress();
let n = null;
try {
n = (await provider.call2(address.toString(), 'seqno')).toNumber();
} catch (e) {
}
return n;
}
}
}
}
/**
* @param secretKey {Uint8Array}
*/
this.deploy = (secretKey) => Contract.createMethod(provider, this.createInitExternalMessage(secretKey));
}
getName() {
throw new Error('override me');
}
/**
* @override
* @protected
* @return {Cell} cell contains wallet data
*/
createDataCell() {
// 4 byte seqno, 32 byte publicKey
const cell = new Cell();
cell.bits.writeUint(0, 32); // seqno
cell.bits.writeBytes(this.options.publicKey);
return cell;
}
/**
* @protected
* @param seqno? {number}
* @return {Cell}
*/
createSigningMessage(seqno) {
seqno = seqno || 0;
const cell = new Cell();
cell.bits.writeUint(seqno, 32);
return cell;
}
/**
* External message for initialization
* @param secretKey {Uint8Array} nacl.KeyPair.secretKey
* @return {{address: Address, message: Cell, body: Cell, sateInit: Cell, code: Cell, data: Cell}}
*/
async createInitExternalMessage(secretKey) {
if (!this.options.publicKey) {
const keyPair = nacl.sign.keyPair.fromSecretKey(secretKey)
this.options.publicKey = keyPair.publicKey;
}
const {stateInit, address, code, data} = await this.createStateInit();
const signingMessage = this.createSigningMessage();
const signature = nacl.sign.detached(await signingMessage.hash(), secretKey);
const body = new Cell();
body.bits.writeBytes(signature);
body.writeCell(signingMessage);
const header = Contract.createExternalMessageHeader(address);
const externalMessage = Contract.createCommonMsgInfo(header, stateInit, body);
return {
address: address,
message: externalMessage,
body,
signingMessage,
stateInit,
code,
data,
};
}
/**
* @protected
* @param signingMessage {Cell}
* @param secretKey {Uint8Array} nacl.KeyPair.secretKey
* @param seqno {number}
* @param dummySignature? {boolean}
* @return {Promise<{address: Address, signature: Uint8Array, message: Cell, cell: Cell, body: Cell, resultMessage: Cell}>}
*/
async createExternalMessage(
signingMessage,
secretKey,
seqno,
dummySignature = false
) {
const signature = dummySignature ? new Uint8Array(64) : nacl.sign.detached(await signingMessage.hash(), secretKey);
const body = new Cell();
body.bits.writeBytes(signature);
body.writeCell(signingMessage);
let stateInit = null, code = null, data = null;
if (seqno === 0) {
if (!this.options.publicKey) {
const keyPair = nacl.sign.keyPair.fromSecretKey(secretKey)
this.options.publicKey = keyPair.publicKey;
}
const deploy = await this.createStateInit();
stateInit = deploy.stateInit;
code = deploy.code;
data = deploy.data;
}
const selfAddress = await this.getAddress();
const header = Contract.createExternalMessageHeader(selfAddress);
const resultMessage = Contract.createCommonMsgInfo(header, stateInit, body);
return {
address: selfAddress,
message: resultMessage, // old wallet_send_generate_external_message
body: body,
signature: signature,
signingMessage: signingMessage,
stateInit,
code,
data,
};
}
/**
* @param secretKey {Uint8Array} nacl.KeyPair.secretKey
* @param address {Address | string}
* @param amount {BN | number} in nanotons
* @param seqno {number}
* @param payload? {string | Uint8Array | Cell}
* @param sendMode? {number}
* @param dummySignature? {boolean}
* @param stateInit? {Cell}
* @param expireAt? {number}
* @return {Promise<{address: Address, signature: Uint8Array, message: Cell, cell: Cell, body: Cell, resultMessage: Cell}>}
*/
async createTransferMessage(
secretKey,
address,
amount,
seqno,
payload = "",
sendMode = 3,
dummySignature = false,
stateInit = null,
expireAt = undefined
) {
if (seqno === null || seqno === undefined || seqno < 0) {
throw new Error('seqno must be number >= 0')
}
const signingMessage = this.createSigningMessage(seqno, expireAt);
if (sendMode === null || sendMode === undefined) {
sendMode = 3;
}
signingMessage.bits.writeUint8(sendMode);
signingMessage.refs.push(Contract.createOutMsg(address, amount, payload, stateInit));
return this.createExternalMessage(signingMessage, secretKey, seqno, dummySignature);
}
/**
* @param secretKey {Uint8Array} nacl.KeyPair.secretKey
* @param seqno {number}
* @param messages {[{toAddress: Address | string, amount: BN, payload?: string | Uint8Array | Cell, sendMode?: number, stateInit?: Cell }]} up to 4 messages
* @param dummySignature? {boolean}
* @param expireAt? {number}
* @return {Promise<{address: Address, signature: Uint8Array, message: Cell, cell: Cell, body: Cell, resultMessage: Cell}>}
*/
async createTransferMessages(
secretKey,
seqno,
messages,
dummySignature = false,
expireAt = undefined,
) {
if (seqno === null || seqno === undefined || seqno < 0) {
throw new Error('seqno must be number >= 0')
}
const signingMessage = this.createSigningMessage(seqno, expireAt);
if (messages.length < 1 || messages.length > 4) {
throw new Error('put 1-4 messages');
}
for (const msg of messages) {
let sendMode = msg.sendMode;
if (sendMode === null || sendMode === undefined) {
sendMode = 3;
}
signingMessage.bits.writeUint8(sendMode);
signingMessage.refs.push(Contract.createOutMsg(msg.toAddress, msg.amount, msg.payload, msg.stateInit));
}
return this.createExternalMessage(signingMessage, secretKey, seqno, dummySignature);
}
}
module.exports = {WalletContract};
Выполнить команду
Для локальной разработки. Не используйте в интернете!