You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.4 KiB
121 lines
4.4 KiB
import BN from "bn.js"; |
|
import {Address, beginCell, Cell, contractAddress, TonClient, WalletContract, WalletV3R2Source} from "ton"; |
|
import {mnemonicToWalletKey} from "ton-crypto"; |
|
|
|
// encode contract storage according to save_data() contract method |
|
// storage#_ total_supply:Coins admin_address:MsgAddress next_admin_address:MsgAddress content:^Cell jetton_wallet_code:^Cell = Storage; |
|
export function minterData(params: { adminAddress: Address; supply: number, nextAdminAddress?: Address, content: Cell, wallet_code: Cell }): Cell { |
|
if (!params.nextAdminAddress) params.nextAdminAddress = params.adminAddress; |
|
return beginCell() |
|
.storeCoins(params.supply) |
|
.storeAddress(params.adminAddress) |
|
.storeAddress(params.nextAdminAddress) |
|
.storeRef(params.content) |
|
.storeRef(params.wallet_code) |
|
.endCell(); |
|
} |
|
|
|
function bufferToChunks(buff: Buffer, chunkSize: number) { |
|
let chunks: Buffer[] = [] |
|
while (buff.byteLength > 0) { |
|
chunks.push(buff.slice(0, chunkSize)) |
|
buff = buff.slice(chunkSize) |
|
} |
|
return chunks |
|
} |
|
|
|
export function makeSnakeCell(data: Buffer) { |
|
let chunks = bufferToChunks(data, 127) |
|
let rootCell = new Cell() |
|
let curCell = rootCell |
|
|
|
for (let i = 0; i < chunks.length; i++) { |
|
let chunk = chunks[i] |
|
|
|
curCell.bits.writeBuffer(chunk) |
|
|
|
if (chunks[i + 1]) { |
|
let nextCell = new Cell() |
|
curCell.refs.push(nextCell) |
|
curCell = nextCell |
|
} |
|
} |
|
|
|
return rootCell |
|
} |
|
|
|
export function getMinterAddress(params: { adminAddress: Address; supply: number, nextAdminAddress?: Address, content: Cell, wallet_code: Cell }, initCodeCell: Cell): Address { |
|
return contractAddress({workchain: 0, initialData: minterData(params), initialCode: initCodeCell}); |
|
} |
|
|
|
const OFF_CHAIN_CONTENT_PREFIX = 0x01 |
|
|
|
export function encodeOffChainContent(content: string) { |
|
let data = Buffer.from(content) |
|
let offChainPrefix = Buffer.from([OFF_CHAIN_CONTENT_PREFIX]) |
|
data = Buffer.concat([offChainPrefix, data]) |
|
return makeSnakeCell(data) |
|
} |
|
|
|
// storage#_ balance:(VarUInteger 16) owner_address:MsgAddressInt jetton_master_address:MsgAddressInt jetton_wallet_code:^Cell = Storage; |
|
export function walletData(params: { balance: number, ownerAddress: Address, jettonMasterAddress: Address, jettonWalletCode: Cell }): Cell { |
|
return beginCell() |
|
.storeUint(params.balance, 15) |
|
.storeAddress(params.ownerAddress) |
|
.storeAddress(params.jettonMasterAddress) |
|
.storeRef(params.jettonWalletCode) |
|
.endCell(); |
|
} |
|
|
|
export function getJettonAddress(ownerAddress: Address, jettonMasterAddress: Address, jettonWalletCode: Cell): Address { |
|
return contractAddress({ |
|
workchain: 0, |
|
initialData: walletData({balance: 0, ownerAddress, jettonMasterAddress, jettonWalletCode}), |
|
initialCode: jettonWalletCode |
|
}); |
|
} |
|
|
|
export function transferMsg(amount: number, recipient: Address) { |
|
return beginCell() |
|
.storeUint(0xf8a7ea5, 32) |
|
.storeUint(0, 64) |
|
.storeCoins(amount) |
|
.storeAddress(recipient) |
|
.storeAddress(recipient) |
|
.storeBit(false) |
|
.storeCoins(0) |
|
.storeBit(false) |
|
.endCell(); |
|
} |
|
|
|
export function TON(): number { |
|
return 1000000000; |
|
} |
|
|
|
// message encoders for all ops (see contracts/imports/constants.fc for consts) |
|
|
|
export function depositMsg(amount: number): Cell { |
|
return beginCell().storeUint(0x77a33521, 32) |
|
.storeUint(0, 64).storeCoins(amount).endCell(); |
|
} |
|
|
|
export function withdrawMsg(amount: BN | number): Cell { |
|
return beginCell().storeUint(0x47d1895f, 32).storeUint(0, 64).storeCoins(amount).endCell(); |
|
} |
|
|
|
export async function getWallet(isTestnet: boolean = true) { |
|
const client = new TonClient({ |
|
endpoint: `https://${isTestnet ? "testnet." : ""}toncenter.com/api/v2/jsonRPC`, |
|
apiKey: isTestnet ? 'bed2b4589201ff3c575be653593f912a337c08eed416b60b02345763b9ee9c36' : 'a1e8a1055a387515158589dc7e9bad3035e7db2b9f9ea5cdad6b727f71e328db' |
|
}); |
|
let deployerMnemonic = process.env.DEPLOYER_MNEMONIC; |
|
if (!deployerMnemonic) throw new Error("DEPLOYER_MNEMONIC env var is not set"); |
|
|
|
// open the wallet and make sure it has enough TON |
|
const walletKey = await mnemonicToWalletKey(deployerMnemonic.split(" ")); |
|
let workchain = 0; |
|
return [WalletContract.create(client, WalletV3R2Source.create({ |
|
publicKey: walletKey.publicKey, |
|
workchain |
|
})), walletKey]; |
|
} |