@soundsright/sdk
Version:
soundsright chain sdk
213 lines (212 loc) • 11.2 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NftMarket = void 0;
const types_1 = require("@soundsright/types");
const utils_1 = require("@soundsright/utils");
const types_2 = require("../types");
const base_1 = __importDefault(require("./base"));
class NftMarket extends base_1.default {
/**
*
* @param payType - 支付类型枚举:enum PayType { ETH = 'ETH', Erc20 = 'Erc20', Currency = 'Currency' }
* @param options - 支付选项:NftBuyOptions
* ```ts
* NftBuyOptions = NftBuyByETHOptions | NftBuyByErc20Options | NftBuyByCurrencyOptions
* // 当payType为PayType.ETH时:
* type NftBuyByETHOptions = {
* skuId: string;
* beforeSwitchChain?: (e: SwitchChainData) => Promise<void> | void; // 钩子函数 - 切换链之前;SwitchChainData = { targetChainId: number, oldChainId: number }
* switchChainSuccess?: (e: SwitchChainData) => void; // 钩子函数 - 切换链成功;SwitchChainData = { targetChainId: number, oldChainId: number }
* switchChainFailed?: (e: Error & SwitchChainData) => void; // 钩子函数 - 切换链失败;SwitchChainData = { targetChainId: number, oldChainId: number }
* beforeOrder?: () => Promise<void> | void; // 钩子函数 - 创建订单前
* afterOrder?: (apiData: any) => Promise<void> | void; // 钩子函数 - 创建订单后
* beforeExchange?: () => Promise<void> | void; // 钩子函数 - 交易合约前
* };
* // 当payType为PayType.Erc20时:
* type NftBuyByErc20Options = {
* skuId: string;
* beforeSwitchChain?: (e: SwitchChainData) => Promise<void> | void; // 钩子函数 - 切换链之前;SwitchChainData = { targetChainId: number, oldChainId: number }
* switchChainSuccess?: (e: SwitchChainData) => void; // 钩子函数 - 切换链成功;SwitchChainData = { targetChainId: number, oldChainId: number }
* switchChainFailed?: (e: Error & SwitchChainData) => void; // 钩子函数 - 切换链失败;SwitchChainData = { targetChainId: number, oldChainId: number }
* beforeOrder?: () => Promise<void> | void; // 钩子函数 - 创建订单前
* afterOrder?: (apiData: any) => Promise<void> | void; // 钩子函数 - 创建订单后
* beforeQueryBalance?: () => Promise<void> | void; // 钩子函数 - 查询余额前。如果sku价格为0,不会执行
* afterQueryBalance?: (balance: string) => Promise<void> | void; // 钩子函数 - 查询余额后。如果sku价格为0,不会执行
* beforeApprove?: () => Promise<void> | void; // 钩子函数 - Approval合约之前。如果sku价格为0,不会执行
* beforeExchange?: () => Promise<void> | void; // 钩子函数 - 交易合约前
* checkBalance?: boolean; // 默认为true,执行购买前优先检查erc余额。如果sku价格为0,无效
* };
* // 当payType为PayType.Currency时:
* type NftBuyByCurrencyOptions = {
* skuId: string;
* payChannel: PayChannel; // enum PayChannel { Checkout = 1 }
* channelOptions?: object; // 支付渠道要求的参数。对于checkout,需要{ payType: 1, countryCode: int型国家编码, userAddress: 国家代码 } 国家代码可选值:GB 英国、US 美国、JP 日本、KR 韩国、SG 新加坡、PH 菲律宾、AE 迪拜、IO 印度
* beforeOrder?: () => Promise<void> | void; // 钩子函数 - 创建订单前
* beforePay?: (order: any) => Promise<void> | void; // 钩子函数 - 支付前
* paySuccess?: () => Promise<void> | void; // 钩子函数 - 支付成功
* payCancel?: () => void; // 钩子函数 - 支付取消
* };
* ```
* @returns Promise<void>,若异常会抛出相应的Error
*/
buyAndMint(payType, options) {
return __awaiter(this, void 0, void 0, function* () {
if (payType === types_1.PayType.ETH) {
return this.buyAndMintByETH(options);
}
if (payType === types_1.PayType.Erc20) {
return this.buyAndMintByErc20(options);
}
return this.buyAndMintByCurrency(options);
});
}
buyAndMintByETH(options) {
return __awaiter(this, void 0, void 0, function* () {
const { skuId, beforeOrder, beforeExchange, afterOrder } = options;
this.chain.checkConnected();
yield this.chain.checkChain(options);
if (beforeOrder) {
yield beforeOrder();
}
const apiData = yield this.service.nft.getBuySignData(skuId);
const { skuInfoVSRSignInfo, tradeNo, tokenId, address } = apiData;
try {
if (afterOrder) {
yield afterOrder(apiData);
}
const { to, tokenURI, skuContractInfo, v, r, s, } = skuInfoVSRSignInfo;
if (beforeExchange) {
yield beforeExchange();
}
yield this.chain.nft.buyAndMint(address, tokenId, to, tokenURI, skuContractInfo, v, r, s, { value: skuContractInfo.price });
}
catch (e) {
this.service.nft.tradeCancel(tradeNo, tokenId);
throw e;
}
});
}
buyAndMintByErc20(options) {
return __awaiter(this, void 0, void 0, function* () {
const { skuId, beforeOrder, beforeQueryBalance, afterQueryBalance, beforeApprove, beforeExchange, afterOrder, checkBalance = true } = options;
this.chain.checkConnected();
yield this.chain.checkChain(options);
if (beforeOrder) {
yield beforeOrder();
}
const apiData = yield this.service.nft.getBuySignData(skuId);
const { skuInfoVSRSignInfo, tradeNo, tokenId, address } = apiData;
try {
if (afterOrder) {
yield afterOrder(apiData);
}
const { to, tokenURI, skuContractInfo, v, r, s, } = skuInfoVSRSignInfo;
if (this.chain.token.compareAmount(skuContractInfo.price, '0') > 0) {
if (checkBalance) {
if (beforeQueryBalance) {
yield beforeQueryBalance();
}
const balance = yield this.chain.token.balanceOf(skuContractInfo.token, this.chain.account);
if (afterQueryBalance) {
yield afterQueryBalance(balance);
}
if (this.chain.token.compareAmount(balance, skuContractInfo.price) < 0) {
throw new types_2.BalanceNotEnoughError(balance);
}
}
if (beforeApprove) {
yield beforeApprove();
}
yield this.chain.token.approve(skuContractInfo.token, this.chain.account, address, skuContractInfo.price);
}
if (beforeExchange) {
yield beforeExchange();
}
yield this.chain.nft.buyAndMint(address, tokenId, to, tokenURI, skuContractInfo, v, r, s);
}
catch (e) {
this.service.nft.tradeCancel(tradeNo, tokenId);
throw e;
}
});
}
buyAndMintByCurrency(options) {
return __awaiter(this, void 0, void 0, function* () {
const { skuId, payChannel, beforeOrder, beforePay, paySuccess, payCancel, channelOptions } = options;
let payed = false;
let payCancelled = false;
let payWindow;
if (beforeOrder) {
yield beforeOrder();
}
const order = yield this.service.nft.createOrder(skuId, payChannel, channelOptions);
if (beforePay) {
yield beforePay(order);
}
if (payChannel === types_1.PayChannel.Checkout) {
window.location.href = order.payUrl;
return;
}
if (payChannel === types_1.PayChannel.Sendwyre) {
payWindow = (0, utils_1.openWindow)(order.payUrl);
const checkCancel = () => {
if (payWindow.closed) {
if (!payed) {
if (payCancel) {
payCancel();
}
payCancelled = true;
}
return;
}
setTimeout(checkCancel, 100);
};
checkCancel();
}
const waitPaySuccess = () => __awaiter(this, void 0, void 0, function* () {
if (!payed) {
const { state } = yield this.service.nft.queryOrderStatus(order.orderNo);
if (+state === 3) {
throw new types_2.PaymentTimeoutError();
}
else if (+state === 4) {
payed = true;
if (payWindow) {
payWindow.close();
}
if (paySuccess) {
yield paySuccess();
}
return;
}
else if (payCancelled) {
throw new types_2.PaymentCancelError();
}
}
yield new Promise((resolve) => {
setTimeout(resolve, 2000);
});
yield waitPaySuccess();
});
yield waitPaySuccess();
});
}
queryCurrencyOrderStatus(orderNo) {
return __awaiter(this, void 0, void 0, function* () {
return this.service.nft.queryOrderStatus(orderNo);
});
}
}
exports.NftMarket = NftMarket;