four-flap-meme-sdk
Version:
SDK for Flap bonding curve and four.meme TokenManager
108 lines (107 loc) • 4.05 kB
JavaScript
import { FourClient, buildLoginMessage } from '../clients/four.js';
import { createTokenOnChain } from '../contracts/tm.js';
import { Wallet, parseEther } from 'ethers';
import { readFileSync } from 'fs';
import { basename } from 'path';
/**
* 根据文件扩展名获取 MIME 类型
*/
function getMimeType(filename) {
const ext = filename.toLowerCase().split('.').pop();
const mimeTypes = {
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif',
'bmp': 'image/bmp',
'webp': 'image/webp',
};
return mimeTypes[ext || 'png'] || 'image/png';
}
export async function createTokenFlow(input) {
const wallet = new Wallet(input.privateKey);
const accountAddress = await wallet.getAddress();
const four = new FourClient({ baseUrl: input.baseUrl });
// 1) 生成 nonce 并签名
const nonce = await four.generateNonce({ accountAddress, verifyType: 'LOGIN', networkCode: input.networkCode });
const message = buildLoginMessage(nonce);
const signature = await wallet.signMessage(message);
// 2) 登录获取 access token
const accessToken = await four.loginDex({
region: 'WEB',
langType: 'EN',
verifyInfo: { address: accountAddress, networkCode: input.networkCode, signature, verifyType: 'LOGIN' },
walletName: 'MetaMask',
});
// 3) 上传图片(或使用传入的 imgUrl)
let imgUrl = input.imgUrl || '';
if (!imgUrl) {
let imageBlob;
let filename;
// 优先使用 imagePath(从文件系统读取)
if (input.imagePath) {
const imageBuffer = readFileSync(input.imagePath);
filename = basename(input.imagePath);
const mimeType = getMimeType(filename);
// 将 Buffer 转换为 Uint8Array
const uint8Array = new Uint8Array(imageBuffer);
imageBlob = new Blob([uint8Array], { type: mimeType });
}
// 否则使用 image Blob
else if (input.image) {
imageBlob = input.image;
filename = undefined; // Blob 没有文件名,让 SDK 自动生成
}
// 都没有则报错
else {
throw new Error('imagePath, image or imgUrl is required');
}
imgUrl = await four.uploadImage(accessToken, imageBlob, filename);
}
// 4) 创建参数(REST)
const createResp = await four.createToken(accessToken, {
// 可自定义参数
name: input.payload.name,
shortName: input.payload.shortName,
desc: input.payload.desc,
imgUrl,
launchTime: input.payload.launchTime ?? Date.now(),
label: input.payload.label,
webUrl: input.payload.webUrl,
twitterUrl: input.payload.twitterUrl,
telegramUrl: input.payload.telegramUrl,
preSale: input.payload.preSale,
onlyMPC: input.payload.onlyMPC ?? false, // 默认为 false(普通代币)
// 固定参数
lpTradingFee: 0.0025,
symbol: 'BNB',
totalSupply: 1000000000,
raisedAmount: 24,
saleRate: 0.8,
reserveRate: 0,
funGroup: false,
clickFun: false,
});
// 5) 链上创建
// 根据文档:b0Amount(初始金额,默认 8 BNB)+ preSale(预购金额)
const b0AmountStr = input.b0Amount ?? '8'; // 用户可自定义,默认为 8 BNB
const b0Amount = parseEther(b0AmountStr);
const preSaleAmount = input.payload.preSale !== '0' ? parseEther(input.payload.preSale) : 0n;
const valueWei = b0Amount + preSaleAmount;
const { receipt, tokenAddress } = await createTokenOnChain({
chain: input.networkCode,
rpcUrl: input.rpcUrl,
signerPrivateKey: input.privateKey,
args: createResp.createArg,
signature: createResp.signature,
valueWei,
});
return {
accountAddress,
accessToken,
imgUrl,
api: createResp,
txReceipt: receipt,
tokenAddress,
};
}