Skip to content

canyacoin/canpay

Repository files navigation


Mirror This repo mirrors from Gitlab to Github. Please commit to the Gitlab repo: https://gitlab.com/canyacoin/canyacore/canpay


CanPay

Angular component for accepting payments in CAN through a seamless user experience using an a configurable params, See how does it work.

Overview

Accepting payment with token in any dApp can be cumbersome because a developer needs to do mulitple checks and transactions in order to finalize a payment and same applies for the CanYaCoin (CAN).

To streamline the process, we've created a component that takes care of the following:

  • Check for the installed user wallet (Metamask or Trust)
  • Guide the user to install or unlock the wallet
  • Check the user CAN balance
  • Allow a user to buy CAN or ETH (for gas) if he doesn't have enough balance
  • Paying in CAN in a dApp, requires 2 transactions:
    • First, user has to authorise a payment from his address to the dApp address
    • Second, the dApp needs to withdraw the authorised funds and complete the user operation.
  • Allow a user to buy CAN's if he doesn't have enough .
  • Allow a user to buy CAN's with ETH or supported ERC20 token.
  • Before poping up Metamask dialog to the user to execute a transaction, the wizard explains the transaction purpose and what's going to happen.
  • After authorising a payment, the wizard calles (optionally) configured callback so the developer can do the authorised payment through his dApp contract.
  • A callback is triggered upon successful completion for the whole operation
  • Lastly, the component is configurable so it can be embedded inline or used as popup modal dialog.

Usage

Component is packed in an npm package and can be used as normal angular module.

Installation

In your module file:

  import { CanpayModule } from 'canpay-lib';

  // include the module in your imported modules with (optional) configuration object
  @NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    CanpayModule.forRoot({
      useTestNet: <TRUE_FALSE>,
      contracts: {
        canyaCoinAddress: <CanYaCoin_ADDRESS>,
        canyaAbi: <CanYaCoin_ABI> // optional, default is set the prod CanYaCoin ABI
      }
    })
  ],
  providers: [],
  bootstrap: [AppComponent],
})

Using as Inline-Component

  // In your controller file, define an object with the following params
  canPay = {
    dAppName: 'CANWork',
    recipient: <CANWORK_CONTRACT_ADDRESS>,
    amount: <AMOUNT_IN_CAN>,
    complete: <CALLBACK_ON_SUCCESS>,
    cancel: <CALLBACK_ON_CANCEL>
  }
  <!-- In your template file -->
  <canyalib-canpay
    [dAppName]="canPay.dAppName"
    [successText]="canPay.successText"
    [recipient]="canPay.recipient"
    [amount]="canPay.amount"
    (complete)="canPay.complete($event)"
    (cancel)="canPay.cancel($event)"  
  ></canyalib-canpay>

Modal-Component (Popup Dialog)

Nothing to be defiend in the template file, only in the controller file.

  // In your controller file, define an object with the following params
  canPay = {
    dAppName: 'CANWork',
    recipient: <CANWORK_CONTRACT_ADDRESS>,
    amount: <AMOUNT_IN_CAN>,
    complete: <CALLBACK_ON_SUCCESS>,
    cancel: <CALLBACK_ON_CANCEL>
  }

  constructor(private canPayService: CanPayService) { }

  open() {
    this.canPayService.open(this.canPay);
  }

  onCancel(){
    this.canPayService.close();
  }

Component Configuration

Here is a list of the full list of peroperties to configure the CANPay component.

Property Description
dAppName Name of the dApp to be displayed to the user as a merchant name.
onAuthTxHash Function to execute once the hash of the transaction is returned from the authorisation operation.
onPaymentTxHash Function to execute once the hash of the transaction is returned from the payment operation.
recipient The dApp contract address that will receive the payment
amount Optional If set, no amount-input-box will be displayed to the user and the specified amount will be forced.
minAmount Optional If amount is set, this will be the minum accepted amount from the user.
maxAmount Optional If amount is set, this will be the maximum accepted amount from the user.
complete Callback to be triggered upon successful completion of the whole wizard steps.
Input: CanPayData
cancel Callback to be triggered if the user cancelled the wizard.
Input: CanPayData
postAuthorisationProcessName Optional Action name to be exexuted after payment authorisation, Ex: 'Task Deposit'.
startPostAuthorisationProcess Optional callback to be triggered after a user authorisation for the requested amount. It's used to allow a developer to execute external/extended payment operation from the CanYaCoin contract to the dApp contract.
Input: CanPayData
postAuthorisationProcessResults Optional if postAuthorisationProcessName is set. It's used to notify the wizard of the success or failure of the postAuthorisationProcess.
destinationAddress It is the destination address of the user where the CANS will be transferred.
userEmail It is the email address of the user.

Interfaces

CANPay

interface CanPay {
  dAppName: string;
  operation?: Operation;
  onAuthTxHash? : Function;
  recipient: string;
  amount?: number;
  minAmount?: number;
  maxAmount?: number;
  postAuthorisationProcessName?: string;
  postAuthorisationProcessResults?: ProcessActionResult;
  canyaContract?: Contract;
  startPostAuthorisationProcess?: Function;
  complete: Function;
  cancel?: Function;
  currentStep?: Function;
  destinationAddress: string;
  userEmail: string;
}

Wizard Steps

The following are the enum for full wizard steps:

enum Step {
  metamask = 0,
  paymentAmount = 1,
  balanceCheck = 2,
  buyCan = 3,
  authorisation = 4,
  payment = 5,
  process = 6,
  confirmation = 7,
  completed = 8,
  details = 9,
  staging = 10,
  erc20 = 11,
  complete = 12,
  qr = 13,
  error = 14
}

Operation

Type of CanPay operations, default is Authorise.

enum Operation {
  auth = 'Authorise', // Request user authoisation to withdraw CAN
  pay = 'Pay' // Request user to pay CAN directly to the specified recipient
  interact = 'Interact' // Go straight to the post auth process
}

ProcessActionResult

A message to notify CANPay with the postAuthorisationProcess execution results.

interface ProcessActionResult {
  type: ProcessAction; // { success = 0, error = 1 }
  msg: string; // in case of an error, optional error message to be specified
}

CanPayData

Data passed to the callback functions (complete, cancel and startPostAuthorisationProcess)

Property Description
amount Amount specified by either the developer or entered by the user
account User eth address
balance User CAN balance
step Current wizard Step

View

Customize the wizard UI to fit in small areas

enum View {
  Normal, // default
  Compact
}

Helpers

setProcessResult

A utility function that sets the postAuthorisationProcessResults based on the passed in transaction param. See usage example

function setProcessResult(txOrErr) {
  this.postAuthorisationProcessResults = {
    type: !txOrErr.status ? ProcessAction.error : ProcessAction.success,
    msg: !txOrErr.status ? (txOrErr.message || 'Transaction failed') : null
  };
}

Complete Example

The CanPayExample is a fully working example on how to use the CanPay with postAuthorisationProcess params.

Running the Example App

  • Run git clone git@github.com:canyaio/Common.git && cd Common && git checkout lib/canpay && npm i
  • Start your local test net 'truffle' instance by running ganache-cli --port 9545
  • From main project directory, deploy CanYaCoin and Dao contracts to your testnet by running npm run init-deploy-contracts
  • Update environment vars with the deployed contract addresses, you will find the addresses in the file zos.local.json under ./src/ directory
  • Update global vars with appropriate staging address.
  • Run npm run build_lib && npm start
  • Open your browser at http://localhost:4200
  • Done!