NAV Navbar
javascript
  • Introduction
  • Platform Components
  • Architecture
  • Getting started
  • Authentication & Identity
  • Listing
  • Purchase
  • Listing Schemas
  • Getting help
  • Contributing
  • Introduction

    Origin provides a simple and powerful javascript library for developers to build decentralized marketplaces, allowing buyers and sellers to meet and transact without requiring any trusted intermediaries.

    Usage

    Visit our Github: https://github.com/OriginProtocol

    This API documentation will explain how developers can use the origin.js library to create and manage decentralized marketplaces that are built on top of IPFS and the Ethereum network.

    Origin.js aims to create an easy and flexible abstraction layer that:

    Origin.js enables developers to create DApps that onboard new users to the Origin platform, add new listings to the listings registry, create booking contracts, close out bookings (transfer funds, write reviews, etc.), and more.

    Notes

    Please note this project is still in heavy development and many of the features described below have not been implemented yet. This library should not be considered as production-ready.

    Origin.js and the entire Origin Protocol project is 100% open-source and we welcome contributions from the community. There are many ways to help, from reporting issues and contributing code to helping us improve and grow our community.

    If you are interested in getting involved, please read our section on contributing. If at any point you get stuck, please reach out and we'll do our best to help.

    Platform Components

    Origin.js provides the interface for developers to interact with the rest of the Origin platform, all without writing Solidity code or managing IPFS instances.

    At a high-level, the Origin platform consists of user, listing, and booking data and logic stored on the decentralized tech stack. Mission-critical data and logic such as booking availability, transaction history, and escrow rules are generally stored on chain in a series of Ethereum smart contracts. Related metadata such as listing descriptions and images are stored on IPFS, with pointers to this data in the form of content hashes being stored on chain.

    User Registry

    The Origin user registry is a datastore of all Origin-enabled users. Origin users are identified by their Ethereum wallet addresses. In addition, the user registry also stores a mapping of all forms of identity verification that the user has successfully undertaken.

    Origin.js enables developers to register users to the shared user registry, as well as query for identity verifications.

    Listing Registry

    The listing registry stores all valid Origin listings, from cars for rent to freelance design services. Developers will be able to create new listings in JSON, then push them to the Origin listing registry. Under the covers, Origin.js handles the creation of new IPFS content files for static metadata and new entries to the Origin listing registry smart contract.

    Note that Origin.js does not support browsing and searching the listing registry directly. It is recommended that developers use our open-source bridge server to efficiently query the blockchain.

    Booking Contracts

    Booking contracts are automatically created when buyers book listings on Origin-powered DApps. These individual smart contract instances are generated and deployed with rules around price, reservation time, and payment rules. For certain listing types, Origin.js will also generate additional contract code for arbitration, escrow, deposits, payment schedules, etc.

    Contract Modularity

    Origin smart contracts are designed to be flexible and modular. We recognize the need for developers and entrepreneurs to have a choice in selecting smart contract components that tailor-serve their needs.

    To that end, we will provide default contracts for escrow, arbitration, and insurance that will be inherited by our booking smart contracts. However, developers will be able to specify alternative contracts of their choosing (either their own or approved third-party contracts) in Origin.js function calls to generate custom booking contracts.

    Architecture

    If you're new to the space, it may be helpful to first familiarize yourself with some of the core technologies that we're using to build Origin, such as JSONSchema, IPFS and Ethereum.

    Origin listings can be created using a frontend DApp to publish a JSON data object to any publicly writeable IPFS gateway. This JSON data object must conform to a set of standards and validation rules to be considered valid on the network. Users can optionally sign their listings cryptographically to verify their identity using publicly auditable proofs or trusted third parties. The IPFS gateway will publish the listing to the IPFS network making the listing instantly available via hundreds of distributed computers around the world to anyone who knows the content hash. The content hash of the listing is then sent to a smart contract which formally publishes the listing and stores pricing and availability information along with any specified booking rules and policies.

    Listings can easily be searched, browsed, and booked via a frontend DApp. Since we anticipate having too many listings to reasonably parse in a browser, the frontend DApp connects to an open-source bridge server of the user’s choosing, making it possible to search and filter the entire public corpus of listings. Once a listing has been selected, a user can make a booking by sending payment to the booking smart contract along with the IPFS hash of the chosen listing and the desired interval to book. The smart contract will verify that the booking is valid and handle the transfer of tokens between the buyer and the seller, including the escrow of funds when applicable.

    We anticipate most sellers will prefer to list their prices in fiat currencies which often have less volatility than digital currencies. To solve this challenge, both the booking smart contract and the bridge servers will use a common set of oracles and a shared algorithm to determine the exchange rate to be used. This allows prices to be shown to end users in their preferred fiat currencies while the correct amount of digital tokens are sent during the booking. A diverse set of oracles will be chosen to avoid introducing single points of failure into the system.

    Sellers are responsible for disclosing their preferred messaging channels in their listings through which buyers can contact them before, during, or after a transaction. Buyers can similarly indicate their preferred messaging channels when they complete a booking. Non-transactional communication between buyers and sellers will occur off-chain, and both parties are encouraged to only use secure and verifiable communication channels. For transactions that have a possibility of needing arbitration, a multisignature messaging channel should be chosen that includes the arbitrator in all communications.

    Once a transaction is complete, users are encouraged via economic incentives to leave feedback about the interaction in the form of a rating or review. Once again, the content is stored on IPFS and only the content hash is stored on Ethereum. Users are able to establish their reputations over time with verified transactions, building a unified reputation across multiple listing verticals. Buyers can use different wallets with varying levels of identity attached for sensitive transactions, or choose to only reveal their true identity to the seller while using a throw-away wallet.

    Listing policies around escrow, refunds, required deposits, and cancellations are set by the seller and are strictly enforced by the booking smart contract. Any exceptions to the policies must be handled directly off-chain by the two parties.

    JSONSchema

    Learn more about JSONSchema

    Ethereum

    Learn more about Ethereum

    IPFS

    Learn more about IPFS

    Getting started

    Download Origin

    Origin.js is under active development. Our latest releases are available on our Github.

    Use an Ethereum-enabled browser

    For testing and interacting with your DApp, you will need to use a browser that supports Web3. We recommend using the Metamask Chrome Browser Extension. This will enable you to connect to the Ethereum network from your browser. Metamask allows you to run Ethereum DApps right in your browser without running a full Ethereum node.

    Alternatively, you can run the official Ethereum browser Mist.

    On mobile, we recommend trying Toshi, Cipher and Trust Wallet.

    Acquire Test ETH

    Our smart contracts are currently deployed on the Rinkeby testnet. You will need to have test ETH to use this library. You can request test funds from the Rinkeby faucet. Do not yet send real ETH on the Origin network. Use Rinkeby testnet ETH instead.

    Hello World

    Simply include the downloaded javascript library in your html to get started.

    Sample app

    <html>
    <title>Hello World</title>
    <body>
      <script type="text/javascript" src="origin.js"></script>
    </body>
    </html>
    
    const origin = new Origin();
    
    const listingData = {
      name: "Kettlebell For Sale",
      category: "Health and Beauty",
      location: "San Fransisco, CA",
      description:
        "32kg gorilla kettlebell. Mint condition.",
      pictures: [],
      price: 0.134
    }
    const schema = "for-sale"
    const transaction = await origin.listings.create(listingData, schema)
    await origin.contractService.waitTransactionFinished(transaction.tx)
    

    Authentication & Identity

    Identity with ERC 725

    Users identities are tied to Ethereum addresses and your private keys are used as the sole method of authentication on the Origin platform.

    Users can always prove ownership of a wallet without sending funds, simply by signing a message using their private keys.

    Users can assume multiple identities by creating multiple wallets. In this manner, users can choose how much of their off-line identities they wish to reveal to other users while participating on the Origin network.

    We are using the ERC 725 identity standard as proposed by Fabian Vogelsteller as the basis for identity on the Origin platform. We've built an identity playground to help people understand ERC 725 and how it works.

    The Origin run bridge server will provide identity attestations as a community service. Origin identities are portable not only across marketplaces built on our platform, but also with other DApps that are supporting the ERC 725 standard.

    Listing

    A listing is an offer from a seller to sell something.

    It is active until there are no more units available or its expiration date is reached.

    create

    To create a listing

    const listingData = {
      name: "Kettlebell For Sale",
      category: "Health and Beauty",
      location: "San Fransisco, CA",
      description:
        "32kg gorilla kettlebell",
      pictures: [],
      price: 3.3
    }
    const schema = "for-sale"
    const transaction = await origin.listings.create(listingData, schema)
    await origin.contractService.waitTransactionFinished(transaction.tx)
    

    When you create a listing, the API will create both the IPFS data and the Listing contract on the blockchain.

    The fields used come from the listing schema definition used.

    The wallet used to create the listing is used as the seller.

    A listing will expire 60 days after its expiration date.

    buy

    To buy a listing

    const unitstoBuy = 2
    const amountToSend = listing.price * unitstoBuy
    const transaction = await origin.listings.buy(
          listing.address,
          unitstoBuy,
          amountToSend
        )
    await origin.contractService.waitTransactionFinished(transaction.tx)
    

    Buy will create a new Purchase contract on the blockchain. This purchase contract will handle the rest of the transaction between the buyer and the seller.

    close

    To close a listing

    const transaction = await origin.listings.close(
          listing.address
        )
    await origin.contractService.waitTransactionFinished(transaction.tx)
    

    This method is called by the seller.

    Closing a transaction will set the unitsAvailable to zero. This will stop any further purchases of that Listing.

    getByIndex

    To get a listing

    const listing = await origin.listings.getByIndex(1)
    // Returns 
    {
      name: "Kettlebell For Sale",
      category: "Health and Beauty",
      description: "32kg gorilla kettlebell",
      location: "San Fransisco, CA",
      pictures: [],
    
      address: "659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63",
      index: 1,
      ipfsHash: "QmWZDcDq4aYGx9XmkPcx4mnKaGW2jCxf5tknrCtbfpJJFf",
      sellerAddress: "0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4",
      price: 0.004,
      unitsAvailable: 1
    }
    

    Getting a listing will return the fields from the listing according to its listing schema.

    In addition, you'll have fields from the contract on the blockchain.

    allIds

    To find all listing indexes

    const indexes = await origin.listings.allIds()
    // Returns 
    [0,1,2,3,4,5,...]
    

    You can get a simple list of all listing indexes in the registry, which will allow you to loop through fetch information about each Listing.

    Purchase

    A Purchase is a single transaction between a buyer and seller. A single Listing with multiple items for sale could have many Purchases related to it, one for each buyer.

    A Purchase is a stage machine.

    When a Listing is purchased, a new Purchase contract is created. In the simplest, success case, a Purchase moves through the following stages:

    shipping_pendingbuyer_pendingseller_pendingcomplete

    pay

    To pay eth into a purchase

    const transaction = await origin.purchases.pay(purchase_address, amountWei)
    await transaction.isFinished()
    

    This method is called by the buyer when the Purchase is in the "awaiting_payment" stage.

    If the total amount in the Purchase contract is now equal to, or greater than the price of the sale, then the Purchase will change to the "shipping_pending" stage.

    You don't currently need to use this method currently. Purchases are fully funded when bought from Listings.

    sellerConfirmShipped

    To mark a purchase as shipped

    const transaction = await origin.purchases.sellerConfirmShipped(purchase_address)
    await transaction.isFinished()
    

    This method is called by the seller when the Purchase is in the "shipping_pending" stage.

    The Purchase will change to the "buyer_pending" stage. A 21 day timer will start for the buyer to mark the purchase as received. If the buyer does not market the purchase received in this time, it will automatically be marked received at the end of 21 days.

    buyerConfirmReceipt

    To mark a purchase as received

    const transaction = await origin.purchases.buyerConfirmReceipt(purchase_address)
    await transaction.isFinished()
    

    This method is called by the buyer when the Purchase is in the "buyer_pending" stage.

    The Purchase will change to the "seller_pending" stage.

    sellerGetPayout

    To mark a purchase as received

    const transaction = await origin.purchases.sellerGetPayout(purchase_address)
    await transaction.isFinished()
    

    This method is called by the seller when the Purchase is in the "seller_pending" stage.

    The seller will receive all eth value on the contract.

    The Purchase will change to the "complete" stage.

    Listing Schemas

    Since many unrelated developers will be reading and writing to the same data layer, it is essential that everyone adhere to common standards. We will publish and maintain the rules for what constitutes a “valid Origin listing” as well as a library of inheritable JSON schemas for fields commonly used on listings, such as email addresses, URLs, GPS coordinates, international street addresses, international phone numbers and other metadata. These schemas are also easily extensible enabling the creation of new product categories, support for internationalization or other languages as well as other unforeseen use-cases.

    Base Schema

    Every Origin listing must contain some standard fields in order to be considered valid.

    Example Schemas

    Example schemas can be found in the Schemas repository. These need a lot more work.

    Inheritance

    Inherit commonly used fields like:

    Extensibility

    Getting help

    Discord

    Our team collaboration is done in public and our company Discord is open to all. If you have questions or need help getting started, our Discord #engineering channel is a great place to get assistance from our team of engineers and developers.

    Email

    You can also reach us by email at support@originprotocol.com.

    Contributing

    Want to hack on Origin? Awesome!

    Origin is an Open Source project and we welcome contributions of all sorts. There are many ways to help, from reporting issues, contributing code, and helping us improve our community.

    There are three main repositories:

    Dive Right In

    If you're ready to start hacking on Origin right now and you just need an issue to focus on, check out this search of all our currently open issues on Github.

    Read our community guidelines first and have fun!

    Protocol Design

    When considering protocol or implementation design proposals, we are looking for:

    Please note that protocol design is hard, and meticulous work. You may need to review existing literature and think through generalized use cases.

    Community Guidelines

    We want to keep the Origin community awesome, growing and collaborative. We need your help to keep it that way. To help with this we've come up with some general guidelines for the community as a whole:

    Reporting Issues

    If you find bugs, mistakes or inconsistencies in the Origin project's code or documents, please let us know by filing an issue at the appropriate issue tracker (we use multiple repositories).

    Security Issues

    The Origin Protocol and its implementations are still in heavy development. This means that there may be problems in our protocols, or there may be mistakes in our implementations. We take security vulnerabilities very seriously. If you discover a security issue, please bring it to our attention right away!

    If you find a vulnerability please send your report privately to security@originprotocol.com or contact Josh Fraser via Keybase. Please DO NOT file a public issue.

    If the issue is a protocol weakness or something not yet deployed, just discuss it openly.

    Community Improvement

    Origin is just as much about community as it is about our technology.

    We need constant help in improving our documentation, building new tools to interface with our platform, spreading the word to new users, helping new users getting setup and much more.

    Please get in touch if you would like to help out. Our general channel on Discord is a great place to share ideas and volunteer to help.

    Full Time Positions

    Origin occasionally hires developers for part time or full time positions.

    We have a strong preference for hiring people who have already started contributing to the project. If you want a full time position on our team, your best shot is to engage with our team and start contributing code. It is very unlikely that we would offer you a full time position on our engineering team unless you've had at least a couple approved pull requests first.

    If you are interested, check out the Origin Protocol job listings. If you'd like to help in other ways, propose your ideas on the Origin Discord.