Repository
https://github.com/nirvanaitsolutions/swapsteem
New Features
This contribution is related to the utopian Task Request . To complete the task request, we had to implement Issue which is related to trade process. We strictly had to to provide the following features in a flow :
- For Seller
- Transfer STEEM/SBD to escrow account
- Cancel order before it is approved by the agent, in case you you created the order by mistake or do not want to trade anymore.
- Raise a dispute, in case a buyer has confirmed payment but you have not received fiat in your bank.
- Release escrow, In case a buyer has confirmed payment and you have received fiat in your account.
- For buyer
- Approve escrow, in case you agree with the terms of trade and want to go ahead with the transaction.
- Reject escrow, in case you are no longer willing to trade.
- Confirm Payment, When order is approved by the agent and you have transferred the fiat to specified account.
- Raise a dispute, in case a seller has not released payment after you have paid the fiat.
- For Seller
To complete the above features, I created a new order component that will appear just after order creation in the purchase component for open trade. I have have implemented the logic to identify the current user as buyer or seller as shown in below snippet.
if (data.order_type === 'buy') {
this.sender = data.createdfor;
this.reciever = data.createdby;
} else if (data.order_type === 'sell') {
this.sender = data.createdby;
this.reciever = data.createdfor
}
The trade starts with the Seller transferring the STEEM/SBD into an escrow via an escrow_transfer
- IN order to Implement Escrow transfer by seller , we created a button to generate a steemconnect hot sign url for escrow_transfer and set the agent as
along with the redirect_uri which redirects the user to our application after successful escrow transfer, and we update order status to
escrow_transferusing PUT request to the order API.
transferEscrow() {
const now = moment();
const rDeadline: string = now.add(2, 'hours').format('YYYY-MM-DDTHH:MM:SS');
const eDeadline: string = now.add(3, 'days').format('YYYY-MM-DDTHH:MM:SS');
const steemAmount: number = this.selectedOrder.order_coin == "STEEM" ? this.selectedOrder.order_coin_amount : 0;
const sbdAmount: number = this.selectedOrder.order_coin == "SBD" ? this.selectedOrder.order_coin_amount : 0;
console.log(rDeadline, eDeadline, steemAmount, sbdAmount);
window.location.href = `https://steemconnect.com/sign/escrow-transfer?from=${this.sender}&to=${this.reciever}&agent=${this.agent}&escrow_id=${this.selectedOrder.escrowID}&sbd_amount=${sbdAmount}%20SBD&steem_amount=${steemAmount}%20STEEM&fee=${0.001}%20STEEM&ratification_deadline=${rDeadline}&escrow_expiration=${eDeadline}&json_meta={"terms":"${this.selectedAd.terms}", "order_id": "${this.selectedOrder._id}"}&redirect_uri=${window.location.origin}/order/${this.selectedOrder._id}?status=escrow_transfer`;
}
A Buyer/Seller can cancel an order created for his listing until the order_status is agent_escrow_approved.
- In order to cancel the order from a buyer/seller, we update order status as
canceledusing PUT request to the order API and update the componenent.
updateOrderStatus(order_status: string, getAdd?: boolean) {
this._apiSer.updateSelectedOrderFromAPI(this.selectedOrder._id, JSON.stringify({
order_status
})).subscribe((data) => this.zone.run(() => {
this.selectedOrder = data;
this.selectedOrder.order_status = order_status;
if (data.order_type === 'buy') {
this.sender = data.createdfor;
this.reciever = data.createdby;
} else if (data.order_type === 'sell') {
this.sender = data.createdby;
this.reciever = data.createdfor
}
if (getAdd) {
this._apiSer.getSelectedTradeFromAPI(this.selectedOrder.ad_id).subscribe(res => {
this.selectedAd = res;
console.log(this.selectedAd, 'afjsfhj');
this.router.navigate([`/order/${this.selectedOrder._id}`], {
queryParams: {
status: ''
}
});
});
}
}));
}
Once the Seller has transferred STEEM/SBD to escrow, the Buyer can to approve or reject the escrow transfer.
- In order to implement the Escrow approve/reject from the Buyer, We generate a steemconnect hot sign url and redirect the user to our site , also we update order status to
escrow_approve/escrow_rejectusing PUT request to the order API. ,
approveRejectEscrow(approve: number) {
window.location.href = `https://steemconnect.com/sign/escrow-approve?from=${this.sender}&to=${this.reciever}&agent=${this.agent}&who=${this.userData._id}&escrow_id=${this.selectedOrder.escrowID}&approve=${approve}&json_meta={"terms":"${this.selectedAd.terms}", "order_id": "${this.selectedOrder._id}"}&redirect_uri=${window.location.origin}/order/${this.selectedOrder._id}?status=escrow_${approve ? 'approve' : 'reject'}`;
}
After Approval from the Agent, the Buyer can transfer the fiat to the Seller's specified account via bank tansfer. Once the funds are transferred the Buyer needs the Confirm the payment by clicking the onfirm payment button.
- In order to implement confirm payment from buyer, we update order status as
payment_confirmedusing PUT request to the order API and update the componenent.
updateOrderStatus(order_status: string, getAdd?: boolean) {
this._apiSer.updateSelectedOrderFromAPI(this.selectedOrder._id, JSON.stringify({
order_status
})).subscribe((data) => this.zone.run(() => {
this.selectedOrder = data;
this.selectedOrder.order_status = order_status;
if (data.order_type === 'buy') {
this.sender = data.createdfor;
this.reciever = data.createdby;
} else if (data.order_type === 'sell') {
this.sender = data.createdby;
this.reciever = data.createdfor
}
if (getAdd) {
this._apiSer.getSelectedTradeFromAPI(this.selectedOrder.ad_id).subscribe(res => {
this.selectedAd = res;
console.log(this.selectedAd, 'afjsfhj');
this.router.navigate([`/order/${this.selectedOrder._id}`], {
queryParams: {
status: ''
}
});
});
}
}));
}
After confirmation of of payment by the Buyer, A Seller can release the STEEM/SBD to Buyers account via an escrow_release transaction.
- In order to release escrow from a seller, we generate a steemconnect hot sign url which will redirect the user to our application after successful escrow_release and we update order status to
escrow_releaseusing PUT request to the api.
releaseEscrow() {
const steemAmount: number = this.selectedOrder.order_coin == "STEEM" ? this.selectedOrder.order_coin_amount : 0;
const sbdAmount: number = this.selectedOrder.order_coin == "SBD" ? this.selectedOrder.order_coin_amount : 0;
window.location.href = `https://steemconnect.com/sign/escrow-release?from=${this.sender}&to=${this.reciever}&agent=${this.agent}&who=${this.userData._id}&receiver=${this.reciever}&escrow_id=${this.selectedOrder.escrowID}&sbd_amount=${sbdAmount}%20SBD&steem_amount=${steemAmount}%20STEEM&json_meta={"terms":"${this.selectedAd.terms}", "order_id": "${this.selectedOrder._id}"}&redirect_uri=${window.location.origin}/order/${this.selectedOrder._id}?status=escrow_release`;
}
There are two types of disputes that may arise,
- From Seller - Buyer has Confirmed payment but the seller hasnt recieved it till the deadline.
- From Buyer - Buyer has Cinfirmed payment but the seller hasnt released the STEEM/SBD within the deadline.
- In order to raise a dispute escrow from a buyer/seller, we generate a steemconnect hot sign url which will be redirected to our application after successful operation and we update the order status
buyer_escrow_dispute/seller_escrow_disputeusing PUT request to the api.
raiseDispute(disputeType) {
window.location.href = `https://steemconnect.com/sign/escrow-dispute?from=${this.sender}&to=${this.reciever}&agent=${this.agent}&who=${this.userData._id}&escrow_id=${this.selectedOrder.escrowID}&json_meta={"terms":"${this.selectedAd.terms}", "order_id": "${this.selectedOrder._id}"}&redirect_uri=${window.location.origin}/order/${this.selectedOrder._id}?status=${disputeType}_escrow_dispute`
}
More Features
In order to remove dependency on chat for Account number exchange, we added those fields to listing and order components so that we can make the process more real time. We added the textboxes as per the target currency since there are different paams needed when sending mone within differrent countries. As of now
- IF Target currency is INR
- Account Holder's Name
- Account Number
- IFSC Code
- Bank Name
- Bank Address (optional)
- SWIFT/BIC code (optional)
- IF Target currency is USD
- Account Holder's Name
- Account Number
- ABA Number
- Bank Name
- Bank Address(optional)
- SWIFT/BIC code(optional)
- IF Target currency is KRW
- Account Holder's Name
- Account Number
- Bank Name
- Bank Address(optional)
- SWIFT/BIC code(optional)
You can see the added fields in the screenshot below:
Bug Fixes
- Added checks for API failure and various fixes.
There were many error messages being shown on the browser console because of the absence of the data checks. I implemented validations wherever required to ensure smooth transactions.
Relevant PRs and commits
- https://github.com/nirvanaitsolutions/swapsteem/pull/38
- https://github.com/nirvanaitsolutions/swapsteem/pull/42
- https://github.com/nirvanaitsolutions/swapsteem/commit/4250343d48eea3405e503ff1ba3be1e30137144b
- https://github.com/nirvanaitsolutions/swapsteem/commit/7bdfa52eba60a24c1906e29a5f086f64dd5f3783