dotwallet
Version:
A DotWallet helper library
339 lines (316 loc) • 11.9 kB
text/typescript
import {DWUser} from './dwUser'
import WebRequest from 'web-request'
import {DotWalletResult,Vout, MircoOrderInformation, SupportCoinType,DWError, DepositBalance,PushChainResult,DepositAccount, CreateSignature} from './dwCom'
interface MircoOrderDetail{
merchant_order_sn:string;
amount:number;
item_name:string;
receive_address:string;
pay_time:string;
order_sn:string;
status:number;
create_time:string;
}
interface OrderRequest{
app_id:string;
merchant_order_sn:string;
item_name:string;
order_amount:number;
nonce_str:string;
sign:string;
notice_uri:string;
}
interface PaymentOrder{
app_id:string;
merchant_order_sn:string;
item_name:string;
order_amount:number; //单位
nonce_str:string;
sign:string;
notice_uri:string;
redirect_uri:string;
check_order_uri:string;
opreturn:string; //opreturn hex string
receive_address:string;
// coinType:SupportCoinType;
}
export enum DomainOption{
CN = 'https://www.ddpurse.com',
HK = 'https://overseas.ddpurse.com'
}
export interface ClientOptions{
redirectURI:string,
noticeURI:string,
checkOrderURI:string,
receiveAddress:string,//商家默认收款地址,default receive address
merchantName:string,
timeOut:number,
isMobile:boolean,
domain:DomainOption,
}
export interface OrderResult{
orderSn:string,
redirect:string,
redirectFront:string,
}
export class DWMerchant {
public m_appID:string;
public m_secret:string;
public m_merchantName:string;
public m_redirectURI:string;
public m_noticeURI:string;
public m_checkOrderURI:string;
public m_receiveAddr:string;
public m_timeout:number;
public m_opts:ClientOptions;
public m_users:DWUser[] =[];
public m_mapUsers:Map<string,DWUser> = new Map<string,DWUser>();
public static DotWalletOpenURL:string = DomainOption.CN;
public static feeToken = "561b756d12572020ea9a104c3441b71790acbbce95a6ddbf7e0630971af9424b";
public m_depositCoinType = SupportCoinType.BSV;
public m_depositAddress = '';
constructor(appID:string, secret:string, opts?:ClientOptions){
this.m_appID = appID;
this.m_secret = secret;
const defaultOpts:ClientOptions = {
redirectURI:'',
noticeURI:'',
checkOrderURI:'',
receiveAddress:'',
merchantName:'',
timeOut:5000,
isMobile:false,
domain:DomainOption.CN
};
opts = opts||defaultOpts;
this.m_redirectURI = opts.redirectURI || '';
this.m_noticeURI = opts.noticeURI || '';
this.m_checkOrderURI = opts.checkOrderURI|| '';
this.m_merchantName = opts.merchantName || "unkown";
this.m_receiveAddr = opts.receiveAddress || '';
this.m_timeout = opts.timeOut || 5000;
DWMerchant.DotWalletOpenURL = opts.domain || defaultOpts.domain;
this.m_opts = opts;
this.initInerval();
}
private async initInerval(){
let userMap = this.m_mapUsers;
setInterval(async function () {
for(let value of userMap){
let user = value[1];
await user.RefreshAccessToken();
}
}, 7200*1000);
}
public GetAuthURL():string{
const getAuthURL = new URL( "openapi/get_code", DWMerchant.DotWalletOpenURL);
getAuthURL.searchParams.append('app_id', this.m_appID);
getAuthURL.searchParams.append('redirect_uri', this.m_redirectURI);
return getAuthURL.href;
}
public GetMircoPaymentURL():string{
const getURL = new URL( "openapi/set_pay_config", DWMerchant.DotWalletOpenURL);
getURL.searchParams.append('app_id', this.m_appID);
getURL.searchParams.append('redirect_uri', this.m_redirectURI);
return getURL.href;
}
public GetUserPayURL(orderSN:string){
let getURL;
if (this.m_opts.isMobile){
getURL = new URL( "wallet/open/pay", DWMerchant.DotWalletOpenURL);
}else{
getURL = new URL( "desktop/open/order", DWMerchant.DotWalletOpenURL);
}
getURL.searchParams.append('order_sn', orderSN);
return getURL.href;
}
public async mpiFeeQuote():Promise<any>{
const orderURL = new URL( "openapi/mapi/feeQuote", DWMerchant.DotWalletOpenURL);
const rsp = await WebRequest.get(orderURL.href,{
timeout:this.m_timeout,
headers:{token:DWMerchant.feeToken}
});
return JSON.parse(rsp.content);
}
public async mpiTxQuery(txid:string):Promise<any>{
const orderURL = new URL( `openapi/mapi/tx/${txid}`, DWMerchant.DotWalletOpenURL);
const rsp = await WebRequest.get(orderURL.href,{
timeout:this.m_timeout,
headers:{token:DWMerchant.feeToken}
});
return JSON.parse(rsp.content);
}
public async mpiSendTx(rawtx:string):Promise<any>{
const orderURL = new URL( `openapi/mapi/tx`, DWMerchant.DotWalletOpenURL);
const rsp = await WebRequest.post(orderURL.href,{
timeout:this.m_timeout,
headers:{
token:DWMerchant.feeToken,
'Content-Type': 'application/json',
}},JSON.stringify({
rawtx:rawtx
}));
return JSON.parse(rsp.content);
}
/**
* 创建订单号,并返回用户授权URL
* @param orderSN
* @param itemName
* @param payAmount
* @param opreturnHex
* @param receiveAddress
* @returns redirect url
* <a href="https://www.ddpurse.com/desktop/open/order?order_sn=948a19d6b779b2abcfd21c0fa0a9a615">https://www.ddpurse.com/desktop/open/order?order_sn=948a19d6b779b2abcfd21c0fa0a9a615</a>
*/
public async CreateOrder(orderSN:string, itemName:string, payAmount:number, opreturnHex:string, receiveAddress:string |undefined):Promise<DotWalletResult>{
//todo, check payAmount >= dust ,
//todo,check receiveAddress.
//todo, add money type support.
let recvMuti = [{
address: receiveAddress || this.m_receiveAddr,
amount: payAmount
}];
return await this.CreateOrderMuti(orderSN, itemName, payAmount, recvMuti, opreturnHex);
}
public async CreateOrderMuti(orderSN:string,itemName:string, payAmount:number,receiveMuti:Vout[], opreturnHex:string):Promise<DotWalletResult>{
let order:PaymentOrder = {
app_id:this.m_appID,
merchant_order_sn:orderSN,
item_name:itemName,
order_amount:payAmount,
nonce_str:new Date().getTime().toString(),
sign:'',
notice_uri:this.m_noticeURI,
redirect_uri:this.m_redirectURI,
check_order_uri:this.m_checkOrderURI,
opreturn:opreturnHex, //opreturn hex string
receive_address:JSON.stringify(receiveMuti),
};
order.sign = CreateSignature(order, this.m_secret);
const orderURL = new URL( "openapi/order", DWMerchant.DotWalletOpenURL);
const rsp = await WebRequest.post(orderURL.href,{
timeout:this.m_timeout,
headers:{
'Content-Type': 'application/json',
}
},JSON.stringify(order));
const result = <DotWalletResult>JSON.parse(rsp.content);
return result;
}
//please call this function when user redirect from dotwallet
public async AddUser(code:string, userName:string){
let newUser = new DWUser(this, userName);
await newUser.GetAccessCode(code);
await newUser.GetUserInfo();
this.m_mapUsers.set(userName, newUser);
}
public GetUser(userName:string):DWUser{
return this.m_mapUsers.get(userName);
}
//---------------------mirco payment 小额支付相关-----------------------------------
/**
* 小额支持订单接口
* @param userName
* @param orderSN
* @param payAmount
* @param opreturnHex
* @param receiveAddress
*/
public async CreateMircoOrder(userName:string, orderSN:string, payAmount:number, opreturnHex:string,receiveAddress:string |undefined):Promise<DotWalletResult>{
let user = this.m_mapUsers.get(userName);
return await user.CreateMircoOrder(orderSN, payAmount, opreturnHex, receiveAddress);
}
/**
* 根据订单号查询小额支付订单详情
* @param orderSN
*/
public async QueryMircoOrder(orderSN:string):Promise<MircoOrderDetail>{
const orderURL = new URL( "openapi/search_order", DWMerchant.DotWalletOpenURL);
const rsp = await WebRequest.create<DotWalletResult>(orderURL.href,{
timeout:this.m_timeout,
method:'POST'
},{
app_id:this.m_appID,
secret:this.m_secret,
merchant_order_sn:orderSN,
}).response;
const result = rsp.content;
let rst:MircoOrderDetail = <MircoOrderDetail>result.data;
return rst;
}
//----------------------push chain data,托管账户数据上链接口---------------------------------------------
public async pushChainCommon(url:string, req:any):Promise<any>{
var rsp = await WebRequest.post(url,{
timeout:this.m_timeout,
method:'POST',
headers:{
'Content-Type': 'application/json',
appid:this.m_appID,
appsecret:this.m_secret,
}
},JSON.stringify(req));
const result = <DotWalletResult>JSON.parse(rsp.content);
if (result.code < 0){
throw new DWError(result.code, result.msg);
}
return result.data;
}
/**
* 查询托管账户余额接口
*/
public async DepositBalance():Promise<DepositBalance>{
const durl = new URL( "openapi/getDepositBalance", DWMerchant.DotWalletOpenURL);
let result = <DepositBalance>await this.pushChainCommon(durl.href, {
coinType:SupportCoinType.BSV,
});
return result;
}
/**
* 获取托管账户信息,主要是托管账户地址,用户需要往该地址充值,数据上链的手续费从该地址扣除
*/
public async DepositAddress():Promise<string>{
const durl = new URL( "openapi/newDepositAccount", DWMerchant.DotWalletOpenURL);
let result = <DepositAccount>await this.pushChainCommon(durl.href, {
coinType:SupportCoinType.BSV,
});
this.m_depositAddress = result.address;
return this.m_depositAddress;
}
/**
* 数据上链接口
* @param opreturn
*/
public async PushChainData(opreturn:string):Promise<PushChainResult>{
const durl = new URL( "openapi/pushChainData", DWMerchant.DotWalletOpenURL);
let result = <PushChainResult>await this.pushChainCommon(durl.href, {
coinType:SupportCoinType.BSV,
opreturn:opreturn,
});
return result;
}
}
/**
* 非托管账户的数据上链服务
* @param email 打点钱包用户的email
* @param signCallback 回调签名服务器
* @param opreturn 要上链的Opreturn
*/
export async function PushChainData(email:string,signCallback:string, opreturn:string):Promise<PushChainResult>{
const durl = new URL( "/api/pushChainData", DWMerchant.DotWalletOpenURL);
var rsp = await WebRequest.post(durl.href,{
method:'POST',
headers:{
'Content-Type': 'application/json',
}
},JSON.stringify({
coinType:SupportCoinType.BSV,
email:email,
opreturn:opreturn,
signCallback:signCallback,
}));
const result = <DotWalletResult>JSON.parse(rsp.content);
if (result.code < 0){
throw new DWError(result.code, result.msg);
}
return result.data;
}