Skip to content

This is a Polkadot Fiat on and off ramp (fully bidirectional), provided by an Off-Chain-Worker (OCW) which connects through a REST-proxy to any bank account supporting the EBICS (Electronic Banking Internet Communication Standard) protocol. The OCW implements a fully pegged stable coin: Incoming bank transaction trigger minting of new stablcoins…

License

element36-io/ocw-ebics

Repository files navigation

codecov Unit tests

Ebics Off-chain Worker Substrate pallet

The repository contains a substrate solo chain that is connected to an arbitrary bank account which supports the EBICS banking interface (ISO20022). It synchronizes balances and transaction of a bank account with the solo chain using an off-chain-worker. This worker also contains extrinsincs to trigger wire-transfers on the connected bank account.

Later we want to use Zero-Knowledge proofs to enable trustless atomic swap between FIAT and any ledger technology. The system will be called Hyperfridge - the whitepaper is here.

Getting Started

Our runtime includes a pallet called fiat-ramps that is responsible for synchronization of bank account state with the on-chain state

Fiat-ramps is located inside /pallets folder. It is an offchain-worker pallet that primarily does two activities:

  • Poll EBICS service to get the latest bank statements and process every transaction
  • Process burn requests registered in the local pallet storage and send unpeg request to EBICS API.

Burn request is a single request to burn, transfer funds from EBICS supporting bank account using extrinsics. Account submits a request to a chain and it is registered in the local storage. Offchain worker picks up the burn request and sends it to the EBICS service. If everything goes well, EBICS service confirms the transaction and includes it in the statement, thus finalizing the burn request. This is done because transactions in traditional banks are not instant and sometimes it takes days to finalize them.

Rust Setup

First, complete the basic Rust setup instructions.

Build

Use the following command to build the node without launching it:

cargo build --release

or use Makefile:

make build

Note: the above code might take long to compile depending on your machine specs

Run

The OWC needs the backend which connects to the bank account, which is provided by this project. We run the test version of the API in our own server and it is used as default API url for the offchain worker. However, sudo user can change the API url by submitting an extrinsic. If you want to run your local backend instance:

docker run -p 8093:8093 e36io/ebics-service 

There are some known issues with running the backend on M1 Silicon chips, so use our server if that's the case.

Now start the OCW. The provided cargo run command will launch a temporary node and its state will be discarded after you terminate the process. After the project has been built, there are other ways to launch the node.

./target/release/node-template --dev --tmp

# or, simply:
make launch-chain

You can run the development node with temporary storage:

./target/release/node-template --dev --tmp
# or, simply:
make launch-chain

Tests

To run unit tests for offchain-worker, execute the following command:

cargo test -p fiat-ramps

# or, simply:
make run-tests

Linting

To run clippy linter, execute the following command:

cargo clippy

Single-Node Development Chain

This command will start the single-node development chain with persistent state:

./target/release/node-template --dev

Purge the development chain's state:

./target/release/node-template purge-chain --dev

Start the development chain with detailed logging:

RUST_LOG=debug RUST_BACKTRACE=1 ./target/release/node-template -lruntime=debug --dev

Test bank accounts

Following test accounts are for Alice, Bob and Charlie, respectively.

{
  "accounts" : [ {
    "ownerName" : "Alice",
    "iban" : "CH2108307000289537320",
    "accountId": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
    "bic" : "HYPLCH22570",
    "offeredAccountId" : "accountname1",
    "nexusBankAccountId" : "CH2108307000289537320"
  }, {
    "ownerName" : "Bob",
    "iban" : "CH1230116000289537312",
    "accountId": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
    "bic" : "HYPLCH22572",
    "offeredAccountId" : "accountname2",
    "nexusBankAccountId" : "CH1230116000289537312"
  }, {
    "ownerName" : "Charlie",
    "iban" : "CH2108307000289537313",
    "accountId": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
    "bic" : "HYPLCH22573",
    "offeredAccountId" : "accountname3",
    "nexusBankAccountId" : "CH2108307000289537313"
  } ]
}

Connect with Polkadot-JS Apps Front-end

Once the node template is running locally, you can connect it with Polkadot-JS Apps front-end to interact with your chain. Click here connecting the Apps to your local node template.

Now you will be able to open the block explorer and see transactions, events that have occured in the blockchain.

For example, you can take a look at chain storage of fiat-ramps here

Inject Signer Account

For the offchain worker to sign transactions, we need to insert authority keys into the chain. This can be done using RPC call author_insert_key which is located in PolkadotJs Apps interface RPC calls section.

For testing puroposes, we can use this account:

key_type: ramp
suri: cup swing hill dinner pioneer mom stick steel sad raven oak practice
public_key: 5C555czPfaHgYhKhsRg2KNCLGCJ82jVsvweTHAnfvT83uy5T

New API url

You can set the new url for the ebics-service via PolkadotJS interface. Follow this link to the Sudo tab and choose FiatRamps.setApiUrl extrinsic. Paste the new url for the API and click Submit transaction. If everything is good, i.e you are the Sudo account and you have the necessary rights, you should see the transaction included in the block and offchain worker starts querying the new API.

Run in Docker

First, install Docker and Docker Compose.

Then run the following command to start a single node development chain.

./scripts/docker_run.sh

This command will firstly compile your code, and then start a local development network. You can also replace the default command (cargo build --release && ./target/release/node-template --dev --ws-external) by appending your own. A few useful ones are as follow.

# Run Substrate node without re-compiling
./scripts/docker_run.sh ./target/release/node-template --dev --ws-external

# Purge the local dev chain
./scripts/docker_run.sh ./target/release/node-template purge-chain --dev

# Check whether the code is compilable
./scripts/docker_run.sh cargo check

About

This is a Polkadot Fiat on and off ramp (fully bidirectional), provided by an Off-Chain-Worker (OCW) which connects through a REST-proxy to any bank account supporting the EBICS (Electronic Banking Internet Communication Standard) protocol. The OCW implements a fully pegged stable coin: Incoming bank transaction trigger minting of new stablcoins…

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published