🍁Pirichain Decentralized Exchange (DEX) Sample Full Codes
This pages explained that how to code for building a new dex via Pirichain
Key Functions:
getTokenName() & getParityName(): These return the token name (
BNB
) and parity (BNB/PIRI
).getCommission(): Returns the slippage value (0.03).
swapInitialize(): Initializes the swap by setting up parity data such as asks, bids, last price, and daily volume if the user is the scenario owner.
checkMyBNBDeposit(): Checks the BNB deposit in the user's wallet, withdraws BNB if needed, and updates liquidity.
depositToken(): Allows depositing PIRI tokens into the liquidity pool.
getMyDepositWallet(): Returns the wallet address for depositing BNB.
checkWalletInitialization(): Ensures that the wallet is initialized with liquidity, asks, bids, and volume data.
blockWallet() & unBlockWallet(): Blocks or unblocks a wallet from performing operations based on the scenario owner's authorization.
determineAmountForBid() & determineAmountForAsk(): These functions calculate how much PIRI or BNB can be bought or sold based on current ask and bid orders.
buyToken(): Facilitates buying PIRI with BNB, checks for blocked wallets, verifies liquidity, and processes the swap.
sellToken(): Facilitates selling PIRI for BNB, checks for blocked wallets, verifies liquidity, and processes the swap.
getAllSlippages(): Returns the slippage fee in both crypto and tokens.
faucetToOwnerForTesting(): Provides liquidity to the owner's wallet for testing purposes.
Error Handling:
The script includes robust error handling for situations like insufficient funds, blocked wallets, ongoing transactions, incorrect data formats, and unauthorized actions.
Slippage:
Slippage is handled as part of the swap, ensuring that any fees are deducted accordingly when buying or selling tokens.
Example Use Cases
Initializing Trading for a BNB and PIRI Pair: Users can call the
swapInitialize
function to set up the liquidity and order books for BNB and PIRI coins.Placing and Removing Orders: Users can place bids and asks at a specific level (
level
) and quantity (quantity
), or remove them if needed.Withdrawing Liquidity: Users can withdraw their available BNB or PIRI token balances from the system using
withdrawBnbWallet
orwithdrawToken
functions.
This structure can be used to build a DEX protocol on Pirichain, or enhance existing exchange integrations by providing automated, blockchain-based trading and liquidity management.
// PIRICHAIN DEX FOR BNB CHAIN BNB COIN
const parity='BNB_PIRI';
const slippage=0.03;
async function getTokenName()
{
return "BNB";
}
async function getParityName()
{
return "BNB/PIRI";
}
async function getCommission()
{
return slippage;
}
async function swapInitialize()
{
if (OWNER_ADDRESS===EXECUTER_ADDRESS)
{
PSDATA[parity]={};
PSDATA[parity].asks=[];
PSDATA[parity].bids=[];
PSDATA['lastPrice']=0;
PSDATA['volumeDaily']=[];
PSDATA['slippageFeeCrypto']=0;
PSDATA['slippageFeeToken']=0;
const result= await Map.saveMap(JSON.stringify(PSDATA));
return result;
}
else
return {error:1,message:'Only scenario owner can execute this function'};
}
async function checkMyBNBDeposit()
{
const myBalanceObj=await getBnbWalletBalance();
const myBalance=parseFloat(myBalanceObj.data);
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (myBalance>0)
{
let withdrawalResultForPSCE={};
checkWalletInitialization();
if (ORIGINFLAG)
{
const scenarioWeb3WalletAddress=await createPSceBnbWallet();
withdrawalResultForPSCE=await withdrawBnbWallet(scenarioWeb3WalletAddress.data);
}
const actualFee=await getBnbFee();
PSDATA[EXECUTER_ADDRESS].liquidityCrypto+=myBalance-actualFee*2;
const depositLiqResult=await Map.saveMap(JSON.stringify(PSDATA));
return {depositLiqResult:depositLiqResult,withdrawalResultForPSCE:withdrawalResultForPSCE};
}
else
return {error:1,message:'There is no BNB at your address'};
}
async function depositToken()
{
if (isNaN(ASSETID))
return {error:-1,message:'AssetID Must be declared,cannot be NAN!'};
if (ASSETID!==-1)
return {error:-1,message:'AssetID Must be -1 for PIRI Coin!'};
if (isNaN(AMOUNT))
return {error:-1,message:'Amount Must be declared,cannot be NAN!'};
if (AMOUNT<=0)
return {error:-1,message:'Amount Must be declared, cannot be zero or negative!'};
checkWalletInitialization();
PSDATA[EXECUTER_ADDRESS].liquidityToken+=AMOUNT;
const depositTokenResult=await Map.saveMap(JSON.stringify(PSDATA));
return depositTokenResult;
}
async function getMyDepositWallet()
{
return await createBnbWallet();
}
async function checkWalletInitialization()
{
if (PSDATA[EXECUTER_ADDRESS]==undefined)
{
PSDATA[EXECUTER_ADDRESS]={};
PSDATA[EXECUTER_ADDRESS].bids=[];
PSDATA[EXECUTER_ADDRESS].asks=[];
PSDATA[EXECUTER_ADDRESS].volume=0;
PSDATA[EXECUTER_ADDRESS].liquidityCrypto=0;
PSDATA[EXECUTER_ADDRESS].liquidityToken=0;
}
}
async function blockWallet(walletAddress,reason)
{
if (OWNER_ADDRESS!==EXECUTER_ADDRESS)
return {error:1,message:'This function must be run by authorized!'};
if (PSDATA['blockedAddress']==undefined)
PSDATA['blockedAddress']=[];
PSDATA['blockedAddress'].push({wallet:walletAddress,reason:reason});
const blockedAddresses=await Map.saveMap(JSON.stringify(PSDATA));
return blockedAddresses;
}
async function unBlockWallet(walletAddress)
{
if (OWNER_ADDRESS!==EXECUTER_ADDRESS)
return {error:1,message:'This function must be run by authorized!'};
if (PSDATA['blockedAddress']==undefined)
return {error:1,message:'There is no blocked addresses'};
PSDATA['blockedAddress']=PSDATA['blockedAddress'].filter(e=>e.wallet!==walletAddress);
const blockedAddresses=await Map.saveMap(JSON.stringify(PSDATA));
return blockedAddresses;
}
async function getBlockAddresses()
{
if (OWNER_ADDRESS!==EXECUTER_ADDRESS)
return {error:1,message:'This function must be run by authorized!'};
return PSDATA['blockedAddress'];
}
async function determineAmountForBid(_bnbAmount)
{
let bnbAmountBool=Validator.isNumeric(_bnbAmount?.toString() || "");
if (!bnbAmountBool)
return {error:1,message:'Wrong Numeric Format bnbAmount'};
let bnbAmount=parseFloat(_bnbAmount);
if (_bnbAmount<=0)
return {error:1,message:'_bnbAmount cannot be negative or zero'};
const currentAsk=PSDATA[parity].asks.sort((a, b) => a.level-b.level);
let spentBnb=0;
let boughtRecords=[];
let boughtQuantity=0;
if (currentAsk.length>0)
{
for (let k=0;k<currentAsk.length;k++)
{
let amo=currentAsk[k].level*currentAsk[k].quantity;
if (bnbAmount>spentBnb && bnbAmount<=spentBnb+amo)
{
if (spentBnb===0 && amo>bnbAmount)
{
// if first record that higher than bnbAmount
let quantity=(bnbAmount/currentAsk[k].level);
boughtRecords.push({level:currentAsk[k].level,quantity:quantity,dateTime:currentAsk[k].dateTime,wallet:currentAsk[k].wallet,residual:true});
amo=currentAsk[k].level*quantity;
boughtQuantity+=quantity;
spentBnb+=amo;
}
else
{
let _remainingAmount=bnbAmount-spentBnb;
let _remainingQuantity=_remainingAmount/currentAsk[k].level;
boughtRecords.push({level:currentAsk[k].level,quantity:_remainingQuantity,dateTime:currentAsk[k].dateTime,wallet:currentAsk[k].wallet,residual:true});
boughtQuantity+=_remainingQuantity;
spentBnb+=currentAsk[k].level*_remainingQuantity;
}
break;
}
else
{
currentAsk[k].residual=false;
boughtRecords.push(currentAsk[k]);
}
spentBnb+=amo;
boughtQuantity+=currentAsk[k].quantity;
}
return {availablePIRI:boughtQuantity,willSpendBNB:spentBnb,boughtRecords:boughtRecords};
}
else
return {error:1,message:'There is no ask order'}
}
async function determineAmountForAsk(_piriQuantity)
{
let piriQuantityBool=Validator.isNumeric(_piriQuantity?.toString() || "");
if (!piriQuantityBool)
return {error:1,message:'Wrong Numeric Format _piriQuantity'};
let piriQuantity=parseFloat(_piriQuantity);
if (piriQuantity<=0)
return {error:1,message:'_piriQuantity cannot be negative or zero'};
const currentBid=PSDATA[parity].bids.sort((a, b) => b.level-a.level);
let spentPiri=0;
let boughtRecords=[];
let availableBNB=0;
if (currentBid.length>0)
{
for (let k=0;k<currentBid.length;k++)
{
let amo=currentBid[k].quantity;
if (piriQuantity>spentPiri && piriQuantity<=spentPiri+amo)
{
if (spentPiri===0 && amo>piriQuantity)
{
// if first record that higher than piriQuantity
let quantity=piriQuantity;
boughtRecords.push({level:currentBid[k].level,quantity:quantity,dateTime:currentBid[k].dateTime,wallet:currentBid[k].wallet,residual:true});
amo=quantity;
availableBNB+=quantity*currentBid[k].level;
spentPiri+=amo;
}
else
{
let _remainingAmount=piriQuantity-spentPiri;
let _remainingQuantity=_remainingAmount;
boughtRecords.push({level:currentBid[k].level,quantity:_remainingQuantity,dateTime:currentBid[k].dateTime,wallet:currentBid[k].wallet,residual:true});
availableBNB+=_remainingAmount*currentBid[k].level;
spentPiri+=_remainingQuantity;
}
break;
}
else
{
currentBid[k].residual=false;
boughtRecords.push(currentBid[k]);
}
spentPiri+=amo;
availableBNB+=currentBid[k].quantity*currentBid[k].level;
}
return {availableBNB:availableBNB,willSpendPiri:spentPiri,boughtRecords:boughtRecords};
}
else
return {error:1,message:'There is no bid order'}
}
async function faucetToOwnerForTesting(amount)
{
if (OWNER_ADDRESS===EXECUTER_ADDRESS)
{
PSDATA[EXECUTER_ADDRESS].liquidityCrypto=amount;
const faucetOperation=await Map.saveMap(JSON.stringify(PSDATA));
return faucetOperation;
}
return {error:1,message:'Unauthorized Operation!'};
}
async function buyToken(bnbAmount)
{
let bnbAmountBool=Validator.isNumeric(bnbAmount?.toString() || "");
if (!bnbAmountBool)
return {error:1,message:'Wrong Format Bnb Amount'};
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (PSDATA['blockedAddress']!=undefined)
{
if (PSDATA['blockedAddress'].find(r=>r.wallet===EXECUTER_ADDRESS))
return {error:1,message:'Your wallet has been blocked!'};
}
if (PSDATA[EXECUTER_ADDRESS].liquidityCrypto<bnbAmount)
return {error:1,message:'Insufficient Crypto! '};
var errors=[];
const currentAsk=PSDATA[parity].asks.sort((a, b) => a.level-b.level);
if (!currentAsk)
return {error:1,message:'There is no asks table record by your given timeStamp!'};
else
{
const results=await determineAmountForBid(bnbAmount);
if (results===undefined)
return {error:1,message:'There is no Ask Table for now!'};
if (results.boughtRecords===undefined)
return {error:1,message:'There is no Ask Table for now!'};
if (!Array.isArray(results.boughtRecords))
return {error:1,message:'There is no Ask Table for now!'};
results.boughtRecords.forEach(f=>{
if (f['residual']===false)
{
// remove relevant record both of list
PSDATA[parity].asks=PSDATA[parity].asks.filter(r=>r.dateTime!==f.dateTime);
PSDATA[f.wallet].asks=PSDATA[f.wallet].asks.filter(r=>r.dateTime!==f.dateTime);
}
else
{
// Residual Detected and subtract to quantites for both of list
if (typeof PSDATA[parity].asks.find(r=>r.dateTime===f.dateTime) !=="undefined")
PSDATA[parity].asks.find(r=>r.dateTime===f.dateTime).quantity-=f.quantity;
else
errors.push({t:'parity',_obj:f,_oppos:PSDATA[parity].asks});
if (typeof PSDATA[f.wallet].asks.find(r=>r.dateTime===f.dateTime) !=="undefined")
PSDATA[f.wallet].asks.find(r=>r.dateTime===f.dateTime).quantity-=f.quantity;
else
errors.push({t:'wallet',w:f?.wallet,_obj:f,_oppos:PSDATA[f.wallet].asks});
}
if (errors.length>0)
return errors;
PSDATA[f.wallet].liquidityCrypto+=f.quantity*f.level*(1-slippage);
PSDATA[EXECUTER_ADDRESS].liquidityToken+=f.quantity*(1-slippage);
PSDATA['slippageFeeCrypto']+=f.quantity*f.level*(slippage);
PSDATA['slippageFeeToken']+=f.quantity*slippage;
PSDATA[EXECUTER_ADDRESS].liquidityCrypto-=f.quantity*f.level;
PSDATA['lastPrice']=f.level;
if (PSDATA['volumeDaily'])
{
let today=`${new Date().getFullYear()}_${new Date().getMonth()}_${new Date().getDate()}`;
if (!PSDATA['volumeDaily'].find(r=>r.date==today))
PSDATA['volumeDaily'].push({date:today,volume:f.quantity*f.level});
else
PSDATA['volumeDaily'].find(r=>r.date==today).volume+=f.quantity*f.level;
}
});
const buyTokenResult=await Map.saveMap(JSON.stringify(PSDATA));
return buyTokenResult;
}
}
async function getAllSlippages()
{
return {
slippageFeeCrypto:PSDATA['slippageFeeCrypto'],
slippageFeeToken:PSDATA['slippageFeeToken'],
}
}
async function sellToken(_piriQuantity)
{
let piriAmountBool=Validator.isNumeric(_piriQuantity?.toString() || "");
if (!piriAmountBool)
return {error:1,message:'Wrong Format Piri Quantity'};
let piriQuantity=parseFloat(_piriQuantity);
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (PSDATA['blockedAddress']!=undefined)
{
if (PSDATA['blockedAddress'].find(r=>r.wallet===EXECUTER_ADDRESS))
return {error:1,message:'Your wallet has been blocked!'};
}
if (PSDATA[EXECUTER_ADDRESS].liquidityToken<piriQuantity)
return {error:1,message:'Insufficient PIRI! '};
var errors=[];
const currentAsk=PSDATA[parity].bids.sort((a, b) => b.level-a.level);
if (!currentAsk)
return {error:1,message:'There is no bids table record !'};
else
{
const results=await determineAmountForAsk(piriQuantity);
if (results===undefined)
return {error:1,message:'There is no Bid Table for now!'};
if (results.boughtRecords===undefined)
return {error:1,message:'There is no Bid Table for now!'};
if (!Array.isArray(results.boughtRecords))
return {error:1,message:'There is no Bid Table for now!'};
results.boughtRecords.forEach(f=>{
if (f['residual']===false)
{
// remove relevant record both of list
PSDATA[parity].bids=PSDATA[parity].bids.filter(r=>r.dateTime!==f.dateTime);
PSDATA[f.wallet].bids=PSDATA[f.wallet].bids.filter(r=>r.dateTime!==f.dateTime);
}
else
{
// Residual Detected and subtract to quantites for both of list
if (typeof PSDATA[parity].bids.find(r=>r.dateTime===f.dateTime) !=="undefined")
PSDATA[parity].bids.find(r=>r.dateTime===f.dateTime).quantity-=f.quantity;
else
errors.push({t:'parity',_obj:f,_oppos:PSDATA[parity].asks});
if (typeof PSDATA[f.wallet].bids.find(r=>r.dateTime===f.dateTime) !=="undefined")
PSDATA[f.wallet].bids.find(r=>r.dateTime===f.dateTime).quantity-=f.quantity;
else
errors.push({t:'wallet',w:f?.wallet,_obj:f,_oppos:PSDATA[f.wallet].bids});
}
if (errors.length>0)
return errors;
PSDATA[f.wallet].liquidityToken+=f.quantity*(1-slippage);
PSDATA[EXECUTER_ADDRESS].liquidityToken-=f.quantity;
PSDATA['slippageFeeCrypto']+=f.quantity*f.level*(slippage);
PSDATA['slippageFeeToken']+=f.quantity*slippage;
PSDATA[EXECUTER_ADDRESS].liquidityCrypto+=f.quantity*f.level*(1-slippage);
PSDATA['lastPrice']=f.level;
if (PSDATA['volumeDaily'])
{
let today=`${new Date().getFullYear()}_${new Date().getMonth()}_${new Date().getDate()}`;
if (!PSDATA['volumeDaily'].find(r=>r.date==today))
PSDATA['volumeDaily'].push({date:today,volume:f.quantity*f.level});
else
PSDATA['volumeDaily'].find(r=>r.date==today).volume+=f.quantity*f.level;
}
});
const sellTokenResult=await Map.saveMap(JSON.stringify(PSDATA));
return sellTokenResult;
}
}
async function removeMyBid(timeStamp)
{
checkWalletInitialization();
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
const currentRecord=PSDATA[EXECUTER_ADDRESS].bids.find(r=>r.dateTime===timeStamp);
if (currentRecord)
{
PSDATA[EXECUTER_ADDRESS].bids=PSDATA[EXECUTER_ADDRESS].bids.filter(f=>f.dateTime!==timeStamp);
PSDATA[EXECUTER_ADDRESS].liquidityCrypto+=currentRecord.quantity*currentRecord.level;
PSDATA[parity].bids=PSDATA[parity].bids.filter(f=>f.dateTime!==timeStamp);
const removingBidResult=await Map.saveMap(JSON.stringify(PSDATA));
return removingBidResult;
}
else
return {error:1,message:'Bid Record that you defined Not Found!'}
}
async function listMyRecord()
{
return PSDATA[EXECUTER_ADDRESS];
}
async function listTables()
{
return {
bids:PSDATA[parity].bids.sort((a, b) => a.level-b.level),
asks:PSDATA[parity].asks.sort((a, b) => a.level-b.level),
lastPrice:PSDATA['lastPrice'],
volumeDaily:PSDATA['volumeDaily']
}
}
async function removeMyAsk(timeStamp)
{
checkWalletInitialization();
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
const currentRecord=PSDATA[EXECUTER_ADDRESS].asks.find(r=>r.dateTime===timeStamp);
if (currentRecord)
{
PSDATA[EXECUTER_ADDRESS].asks=PSDATA[EXECUTER_ADDRESS].asks.filter(f=>f.dateTime!==timeStamp);
PSDATA[parity].asks=PSDATA[parity].asks.filter(f=>f.dateTime!==timeStamp);
PSDATA[EXECUTER_ADDRESS].liquidityToken+=currentRecord.quantity;
const removingAskResult=await Map.saveMap(JSON.stringify(PSDATA));
return removingAskResult;
}
else
return {error:1,message:'Ask Record that you defined not Found!'}
}
async function addBid(quantity,level)
{
if (PSDATA['blockedAddress']!=undefined)
{
if (PSDATA['blockedAddress'].find(r=>r.wallet===EXECUTER_ADDRESS))
return {error:1,message:'Your wallet has been blocked!'};
}
let quantityBool=Validator.isNumeric(quantity?.toString() || "");
if (!quantityBool)
return {error:1,message:'Wrong Format Quantity'};
let levelBool=Validator.isNumeric(level?.toString() || "");
if (!levelBool)
return {error:1,message:'Wrong Format Level'};
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (PSDATA[EXECUTER_ADDRESS].liquidityCrypto>=quantity*level)
{
checkWalletInitialization();
let dateTime=await Tools.getRandom();
PSDATA[EXECUTER_ADDRESS].bids.push({quantity:quantity,level:level,dateTime:dateTime});
PSDATA[parity].bids.push({wallet:EXECUTER_ADDRESS, quantity:quantity,level:level,dateTime:dateTime});
PSDATA[EXECUTER_ADDRESS].liquidityCrypto-=quantity*level;
const addingBidResult=await Map.saveMap(JSON.stringify(PSDATA));
return addingBidResult;
}
else
return {error:1,message:'Insufficent BNB Balance'};
}
async function addAsk(quantity,level)
{
if (PSDATA['blockedAddress']!=undefined)
{
if (PSDATA['blockedAddress'].find(r=>r.wallet===EXECUTER_ADDRESS))
return {error:1,message:'Your wallet has been blocked!'};
}
let quantityBool=Validator.isNumeric(quantity?.toString() || "");
if (!quantityBool)
return {error:1,message:'Wrong Format Quantity'};
let levelBool=Validator.isNumeric(level?.toString() || "");
if (!levelBool)
return {error:1,message:'Wrong Format Level'};
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (PSDATA[EXECUTER_ADDRESS].liquidityToken>=quantity)
{
checkWalletInitialization();
let dateTime=await Tools.getRandom();
PSDATA[EXECUTER_ADDRESS].asks.push({quantity:quantity,level:level,dateTime:dateTime});
PSDATA[parity].asks.push({wallet:EXECUTER_ADDRESS,quantity:quantity,level:level,dateTime:dateTime});
PSDATA[EXECUTER_ADDRESS].liquidityToken-=quantity;
const addingBidResult=await Map.saveMap(JSON.stringify(PSDATA));
return addingBidResult;
}
else
return {error:1,message:'Insufficent Token'};
}
async function _withdrawBnbWallet(withdrawalAddress)
{
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (!withdrawalAddress)
return {error:1,message:'Wrong Format! Please Fix It'};
if (withdrawalAddress==='')
return {error:1,message:'Wrong Format! Please Fix It'};
if (withdrawalAddress.length!=42)
return {error:1,message:'Wrong Format! Please Fix It'};
if (PSDATA[EXECUTER_ADDRESS].liquidityCrypto<=0)
return {error:1,message:'Insufficient Balance!'};
const hexResult=await Validator.isHex(withdrawalAddress.substr(2,withdrawalAddress.length-2));
if (hexResult)
{
let withdrawResult={};
if (ORIGINFLAG)
{
withdrawResult= await withdrawBnbPSceWallet(withdrawalAddress,parseFloat(PSDATA[EXECUTER_ADDRESS].liquidityCrypto));
}
PSDATA[EXECUTER_ADDRESS].liquidityCrypto=0;
const wResult=await Map.saveMap(JSON.stringify(PSDATA));
return {addingBidResult:wResult,withdrawResult:withdrawResult};
}
else
return {error:1,message:'Malformed BNB Address Format!'};
}
async function withdrawToken()
{
const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
if (hasTx.data)
return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
if (PSDATA[EXECUTER_ADDRESS].liquidityToken<=0)
return {error:1,message:'Insufficient Balance!'};
const transferResult=await Transaction.sendPIRI(EXECUTER_ADDRESS,parseFloat(PSDATA[EXECUTER_ADDRESS].liquidityToken));
PSDATA[EXECUTER_ADDRESS].liquidityToken=0;
const wResult=await Map.saveMap(JSON.stringify(PSDATA));
return {wResult:wResult,transferResult:transferResult};
}
Last updated