NAV Navbar
Wolk API

Wolk API for Trustless Web Apps

The Wolk blockchain embodies a next generation HTTP protocol (the Wolk protocl) where web browsing is trustless and serverless, with web browsers interacting not with web servers but with a web blockchain.

The Wolk protocol makes lock-in between users and developers impossible, enabling true digital freedom:

Wolk API

The Wolk API is a Javascript interface that enables developers of web content to store and retrieve data from the Wolk blockchain:

Wolk API Method HTTP Request Method / Path HTTP Request Body HTTP Response Body (200 OK) HTTP Proof Response Header
createAccount PUT wolk/account/owner JSON Account txhash N/A
getAccount GET wolk/account/owner - JSON Account JSON SMTProof
getBlock GET wolk/block/blocknumber - JSON Block verified against blockchain
getLatestBlock GET wolk/block/latest - JSON Block verified against blockchain
getTransaction GET wolk/tx/txhash - JSON Transaction verified against blockchain
createCollection PUT owner/collection JSON Collection definition txhash N/A
listCollections GET owner - JSON Collection JSON ScanProof
deleteCollection DELETE owner/collection - txhash N/A
setKey PUT owner/collection/key ArrayBuffer or JSON Schema txhash N/A
getKey GET owner/collection/key - value JSON NoSQLProof
scanCollection GET owner/collection - []value JSON ScanProof
deleteKey DELETE owner/collection - txhash N/A
createDatabase PUT owner/database/SQL JSON SQLRequest txhash N/A
listDatabases GET owner/database/SQL JSON SQLRequest JSON Database N/A
deleteDatabase DELETE owner/database/SQL JSON SQLRequest txhash N/A
createTable PUT owner/database/table JSON SQLRequest txhash N/A
describeTable GET owner/database/table JSON SQLRequest JSON Columns JSON NoSQLProof
listTables GET owner/database JSON SQLRequest []JSON Table JSON ScanProof
dropTable DELETE owner/database/table JSON SQLRequest txhash N/A
executeSQL POST owner/database/table JSON SQLRequest txhash N/A
readSQL PATCH owner/database/table JSON SQLRequest JSON SQLResponse JSON STARKProof (Not implemented)

The Wolk Class abstracts all HTTP operations in the Wolk API methods that each interact with the Wolk Blockchain, described below.
Unless otherwise noted, all Wolk API methods are asynchronous, supporting both a callback and promise pattern.

Request/Response Headers

Each interaction with a Wolk Blockchain involves submitting signed HTTP requests with Requester being the users public JSON Web Key and Sig holding the users signature (64 hex). A Wolk Browser/Extension will register a user private key with createAccount and is responsible for protecting the users keys and ensuring that application code does not engage in signing actions without the user's permission.
Current implementations have Wolk nodes support for ECDSA-256 with SHA-256 hashes, but in principle any number of curves and hashing functions could be used (e.g. Edwards with Blake).

Request Method HTTP Request Headers HTTP Response Headers
GET Sig, Requester, Proof Proof, Proof-Type
POST, PUT, DELETE, PATCH Sig, Requester -

PUT, POST, DELETE, PATCH requests result in a transaction being submitted to the Wolk Blockchain with a txhash being returned immediately. When consensus is achieved, the transaction is included in a minted block and GET requests can return proofs. Wolk Browsers should send their Proof header in GET requests and Wolk nodes must send Proof and Proof-Type headers in addition to the both.
Each Proof-type is described separately.

Wolk nodes run data sharing and consensus protocols that Wolk API users do not need to concern themselves with but are critical for decentralized storage.

Request Options

GET requests uniformly support an JSON RequestOptions structure to control request behavior, with the following attributes: * blockNumber * maxContentLength * history * range

Wolk Clients

To use the WOLK API and develop Wolk applications, obtain a browser or Chrome extension from:

Anyone can fork these browsers and extensions to develop additional Wolk Clients that interacts with a Wolk blockchain.

Blockchain Methods

The API uses the following core Blockchain types:

createAccount

createAccount(owner, account[, callback])

Asynchronously creates account using owner name and JSON Account object. If callback is not provided, returns a promise.

// promise
wolk.createAccount("jill", {"rsaPublicKey": "..."})
  .then(function(txhash) {
    console.log(txhash);
  })
  .catch(function(err) {
    console.error(err);
  })

// callback
wolk.createAccount("jack", {"rsaPublicKey": "..."}, function(err, txhash) {
    if ( err ) {
      throw(err);
    }
    console.log(txhash);
  })

getAccount

getAccount(owner[, callback])

Asynchronously gets specific account by the account owner, originally created by createAccount. If callback is not provided, returns a promise.

getBlock

getBlock(blockNumber[, callback])

Asynchronously gets specific block number. If callback is not provided, returns a promise.

// promise
wolk.getBlock(42)
  .then(function(block) {
    console.log(block);
  })
  .catch(function(err) {
    console.error(err);
  })
// callback
wolk.getBlock(42, function(err, block) {
    if ( err ) {
      throw(err);
    }
    console.log(block);
  })

getLatestBlock

getLatestBlock([callback])

Asynchronously gets latest block. If callback is not provided, returns a promise.

// promise
wolk.getLatestBlock()
  .then(function(block) {
    console.log(block);
  })
  .catch(function(err) {
    console.error(err);
  })
// callback
wolk.getLatestBlock(blockNumber, function(err, block) {
    if ( err ) {
      throw(err);
    }
    console.log(block);
  })

getTransaction

getTransaction(txhash[, callback])

Asynchronously gets transaction using a transaction hash. If callback is not provided, returns a promise.

// promise
wolk.getTransaction("98827bbd28f1cf65f91dbc0abdb7e50e6bb4a9d4fb69283b1ca5ff828c686a9b")
  .then(function(tx) {
    console.log(tx);
  })
  .catch(function(err) {
    console.error(err);
  })
// callback
wolk.getTransaction("98827bbd28f1cf65f91dbc0abdb7e50e6bb4a9d4fb69283b1ca5ff828c686a9b", function(err, tx) {
    if ( err ) {
      throw(err);
    }
    console.log(tx);
  })

File/NoSQL Methods

The model for file storage and NoSQL is that keys and values are kept in an owner's collections. The difference between File collections and NoSQL collections is that File collections are just blobs of bytes and NoSQL collections are JSON records which may be indexed.

createCollection

createCollection(owner, collection[, callback])

Asynchronously creates new collection, returning a transaction hash. If callback is not provided, returns a promise.

// promise
wolk.createCollection("bruce", "planets")
  .then(function(txhash) {
    console.log(txhash);
  })
  .catch(function(err) {
    console.error(err);
  })
// callback
wolk.createCollection("bruce", "planets", function(err, txhash) {
    if ( err ) {
      throw(err);
    }
    console.log(txhash);
  })

In the next release, we will have index specifiable in CreateCollection, with Range Proofs being returned in scanCollection responses and verified by Wolk clients.

listCollections

listCollections(owner[, callback])

Asynchronously list an owner's collections, returning a list of collections. If callback is not provided, returns a promise.

// promise
wolk.listCollections("bruce")
  .then(function(result) {
    console.log(result);
  })
  .catch(function(err) {
    console.error(err);
  })

// callback
wolk.listCollections("bruce", function(err, result) {
    if ( err ) {
      throw(err);
    }
    console.log(result);
  })

deleteCollection

deleteCollection(owner, collection)

Asynchronously delete an owner's collection, returning transaction hash. If callback is not provided, returns a promise.

// promise
wolk.deleteCollection("bruce", "planets",)
  .then(function(txhash) {
    console.log(txhash);
  })
  .catch(function(err) {
    console.error(err);
  })
// callback
wolk.deleteCollection("bruce", "planets", function(err, result) {
    if ( err ) {
      throw(err);
    }
    console.log(result);
  })

setKey

setKey(owner, collection, key, val[, callback])

Asynchronously sets a key-value pair in an owner's collection. The collection must have already been created with createCollection and to retreive the value the caller must use getKey. If callback is not provided, returns a promise.

// promise
wolk.setKey("bruce", "planets", "pluto", "small")
  .then(function(txhash) {
    console.log(txhash)
  })
  .catch(function(err) {
    console.error(err)
  })

// callback
wolk.setKey("bruce", "planets", "pluto", "small", function(err, txhash) {
  if ( err ) {
    throw(err);
  }
  console.log(txhash);
})

getKey

getKey(owner, collection, key[, callback])

Asynchronously gets the value corresponding to a given key in the owner's collection. Previously, the key-value pair must have been set with setKey. If callback is not provided, returns a Promise.

// promise
wolk.getKey("bruce", "planets", "pluto")
  .then(function(result) {
    console.log(result);
  })

// callback
wolk.getKey("bruce", "planets", "pluto", function (err, result) {
  if ( err ) {
    throw(err);
  }
  console.log(result);
})

scanCollection

scanCollection(owner, collection[, callback])

Asynchronously returns all key-value pairs in a collection. All key-value pairs have been set with setKey transactions. If callback is not provided, returns a Promise.

// promise
wolk.scanCollection("bruce", "planets")
  .then(function(result) {
    console.log(result);
  })
  .catch(function(err) {
    console.error(err);
  })

// callback
wolk.scanCollection("bruce", "planets", function (err, result) {
  if ( err ) {
    throw(err);
  }
  console.log(result);
})  

deleteKey

deleteKey(owner, collection, key)

Asynchronously delete specific key-value pair in an owner's collection. The key-value pair must have been set with setKey operations. If callback is not provided, returns a Promise.

// promise
wolk.deleteKey("bruce", "planets", "pluto")
  .then(function(txhash) {
    console.log(txhash)
  })
  .catch(function(err) {
    console.error(err)
  })

// callback
wolk.deleteKey("bruce", "planets", "pluto"), function(err, txhash) {
  if ( err ) {
    throw(err);
  }
  console.log(txhash);
})

SQL Operations

The Wolk API uses the following data types in SQL Operations: * JSON SQLRequest * JSON SQLResponse

createDatabase

createDatabase(owner, database, options [, callback])

Creates a database owned by owner.

// promise
wolk.createDatabase("alina", "db03", {})
  .then(function(txhash) {
    console.log(txhash);
  })
  .catch(function(err) {
    console.error(err);
  })

// callback
wolk.createDatabase("alina", "db03", {}, function(err, txhash) {
  if ( err ) {
    throw(err)
  }
  console.log(txhash);
})

listDatabases

listDatabases(owner, options)

List databases owned by a user.

// promise
wolk.listDatabases("alina", {})
  .then(function(result) {
    console.log(result);
  })
  .catch(function(err) {
    console.error(err);
  })

// callback
wolk.listDatabases("alina", {}, function(err, result) {
  if ( err ) {
    throw(err)
  }
  console.log(result);
});

{
  result: {
    data: [{
        database: "testdb"
    }],
    matchedrowcount: 1
  }
}

deleteDatabase

deleteDatabase(owner, database)

Aysnchronously deleted a database by specifying owner and database name.

// promise
wolk.deleteDatabase("alina", "db03")
  .then(function(txhash) {
    console.log(txhash)
  })
  .catch(function(err) {
    console.error(err)
  })
// callback
wolk.deleteDatabase("alina", "db03", function(err, txhash) {
  if ( err ) {
    throw(err);
  }
  console.log(txhash)
})

createTable

createTable(owner, database, table, columns, options[, callback])

Asynchronously creates a table with specific column definitions. Note: current supported types for columns are STRING, INTEGER, FLOAT and a table must have a primary key. If callback is not provided, returns a Promise.

// promise
let columns = [{
    "columnname": "person_id",
    "indextype": "BPLUS",
    "columntype": "INTEGER",
    "primary": 1
  }, {
    "columnname": "name",
    "indextype": "BPLUS",
    "columntype": "STRING"
  }]
wolk.createTable("alina", "db03", "person", columns, {})
  .then( function(txhash) {
    console.log(txhash)
  })
  .catch( function(err) {
    console.error(err)
  })
{"txhash": "98827bbd28f1cf65f91dbc0abdb7e50e6bb4a9d4fb69283b1ca5ff828c686a9b"}

// callback
wolk.createTable("alina", "db03", "person", columns, {}, function(err, txhash) {
  if ( err ) {
    throw(err);
  }
  console.log(txhash)
})
{"txhash": "98827bbd28f1cf65f91dbc0abdb7e50e6bb4a9d4fb69283b1ca5ff828c686a9b"}

describeTable

describeTable(owner, database, table, options[, callback])

Shows the definition of a table in an owner's database.

// promise
wolk.describeTable("alina", "db03", "person", {})
   .then( function(result) {
     let res = JSON.parse(result);
     console.log(res)
   })
   .catch( function(err) {
     console.error(err);
   })

// callback
wolk.describeTable("alina", "db03", "person", {}, function(err, result) {
     let res = JSON.parse(result);
     console.log(res)
   })
{"data":[{"ColumnName":"name","ColumnType":"STRING","IndexType":"BPLUS","Primary":0},{"ColumnName":"person_id","ColumnType":"INTEGER","IndexType":"BPLUS","Primary":1}]}

listTables

listTables(owner, database, options)

Lists the tables in an owner's database.

// promise
wolk.listTables("alina", "db03", {})
  .then(  function(result) {
     console.log("list tables:", result)
     let res = JSON.parse(result);
   })
  .catch( function(err) {
    console.error(err)
  })
// callback
wolk.listTables("alina", "db03", {}, function(err, result) {
     console.log("list tables:", result)
     let res = JSON.parse(result);
   })
{
  result: {
    data: [{
        table: "demoitems"
    }],
    matchedrowcount: 1
  }
}

dropTable

dropTable(owner, database, table, options[, callback])

Asynchronously drop a table by specifying table name in an owner's database.

// promise
wolk.dropTable("alina", "db03", "person", {})
  .then( function(txhash) {
    console.log(txhash)
  })
  .catch( function(err) {
    console.error(err)
  })
// callback
wolk.dropTable("alina", "db03", "person", {}, function(err, txhash) {
  if ( err ) {
    throw(err);
  }
  console.log(txhash)
})

executeSQL

executeSQL(owner, database, sql, options[, callback])

Asynchronously executes SQL query in an owner's database.

INSERT Query

// promise
var sql_insert = "INSERT INTO demoitems(ID, Name, Description, Price, Currency, Hash) VALUES('ID1','Item1','Hot Item #1',0.11,'ethereum', 'Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u')";
wolk.executeSQL("alina", "db03", sql_insert, {})
  .then(function(txhash) {
    console.error(txhash)
  })
  .catch(function(err) {
    console.error(err)
  })

// callback
wolk.executeSQL("alina", "db03", sql_insert, {}, function(err, txhash) {
  if ( err ) {
      throw(error);
  }
  console.log(txhash)
})

UPDATE Query

// promise
var sql_update = "UPDATE demoitems SET Price = 0.13 WHERE ID='ID2'"
wolk.executeSQL("alina", "db03", sql_update, {})
  .then(function(txhash) {
    console.error(txhash)
  })
  .catch(function(err) {
    console.error(err)
  })

// callback
wolk.executeSQL("alina", "db03", sql_update, {}, function(err, txhash) {
  if ( err ) {
      throw(error);
  }
  console.log(txhash)
})

DELETE Query

// promise
var sql_delete = "DELETE FROM demoitems WHERE ID='ID1'"
wolk.executeSQL("alina", "db03", sql_delete, {})
  .then(function(txhash) {
    console.error(txhash)
  })
  .catch(function(err) {
    console.error(err)
  })

// callback
wolk.executeSQL("alina", "db03", sql_delete, {}, function(err, txhash) {
  if ( err ) {
      throw(error);
  }
  console.log(txhash)
})

readSQL

readSQL(owner, database, sql, options)

Executes read-only SQL query in an owner's database.

// promise
var sql_select = "SELECT * FROM demoitems WHERE price > 0.10"
wolk.readSQL("alina", "db03", sql_select, {})
  .then(function(result) {
    let res = JSON.parse(result);
    console.log(res.data);
  })
  .catch(function(err) {
    console.error(err)
  })

// callback
wolk.readSQL("alina", "db03", sql_select, {}, function(err, result) {
  if ( err ) {
    throw(err);
  }
  let res = JSON.parse(result);
  console.log(res.data);
});

// result:
{
  result: {
    data: [{
        ID: "ID1",
        Name: "Item1",
        Description: "Hot Item #1",
        Price:0.11,
        Currency:'ethereum',
        Hash:'Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u'
    },{
        ID: "ID2",
        Name: "Item2",
        Description: "Hot Item #2",
        Price:0.09,
        Currency:'ethereum',
        Hash:'Qme1gTwdtFaUMoqwTNWX5SdYmNfiAj4N88qujbxmsX5z6u'
    }],
    matchedrowcount: 2
  }
}

Errors

[This is undergoing revision now.]

The Wolk API uses the following error codes:

Error Code Meaning
400 Bad JSON supplied: [JSON]
401 SQL Parsing error: [SQLError in SQL]
402 Key Not Found: [key]
403 Table Does Not Exist: Table: [tableName] Owner: [ownerID]
404 Column Does Not Exist in table definition: [columnName]
405 No Primary Key specified in Create Table
406 Multiple Primary keys specified in Create Table
407 Invalid ColumnType: [columnType]
408 Invalid IndexType: [indexType]
409 Max Allowed Columns exceeded - [Num Columns] supplied, max is [MaxNumColumns]
410 Max Allowed Record size exceeded - [RecordSize] provided,
411 Error on Write [Details]
412 Error on Read [Details]
413 ENS Error
414 Invalid Challenge Response
415 Insufficient Permissions
416 No Table Owner specified
417 Table Owner mismatch
418 Request Invalid
419 Invalid Signature Length: Must be 65 characters
420 Invalid Signature: Unable to Retrieve Public Key
421 User Address not configured on connected node.
422 Unable to decode response
423 Error Decoding Signed Message
424 Error In HTTP Request
425 Invalid Query Request. Missing Rawquery
426 Table Name Missing
427 Mismatched Column Types
428 Row missing primary key
429 Row contains unknown column [columnName]
430 TableOwner Missing
431 Scans on Column [column] not unsupported due to indextype
432 WHERE Clause contains invalid column [column name]
433 GET Request Missing Key
434 Record with key [keyvalue] already exists. If you wish to modify, please use UPDATE SQL statement or PUT
435 Invalid Row Data
436 Unable to converty byte array to Row Object
437 ColumnType [type] not SUPPORTED. Value [value] rejected
438 Invalid Request Body
439 Failure to store [CHUNKTYPE] Chunk
440 Enable to retrieve [CHUNKTYPE] Chunk