diff --git a/package.json b/package.json
index 69c877b1..d139f21a 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "interface-ipfs-core",
   "version": "0.15.0",
   "description": "A test suite and interface you can use to implement a IPFS core interface.",
-  "main": "lib/index.js",
+  "main": "src/index.js",
   "jsnext:main": "src/index.js",
   "scripts": {
     "test": "exit(0)",
@@ -28,6 +28,7 @@
   },
   "homepage": "https://github.com/ipfs/interface-ipfs-core#readme",
   "dependencies": {
+    "async": "^2.0.1",
     "bl": "^1.1.2",
     "bs58": "^3.0.0",
     "chai": "^3.5.0",
@@ -36,6 +37,7 @@
     "ipfs-block": "^0.3.0",
     "ipfs-merkle-dag": "^0.7.0",
     "multihashes": "^0.2.2",
+    "promisify-es6": "^1.0.2",
     "readable-stream": "1.1.13",
     "run-series": "^1.1.4"
   },
@@ -51,4 +53,4 @@
     "greenkeeperio-bot <support@greenkeeper.io>",
     "nginnever <ginneversource@gmail.com>"
   ]
-}
\ No newline at end of file
+}
diff --git a/src/block.js b/src/block.js
index 7512bb01..1543a475 100644
--- a/src/block.js
+++ b/src/block.js
@@ -46,13 +46,14 @@ module.exports = (common) => {
 
       it('.put a block', (done) => {
         const expectedHash = 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ'
-        const blob = new Block(new Buffer('blorb'))
-
-        ipfs.block.put(blob, (err, block) => {
+        Block.create(new Buffer('blorb'), (err, blob) => {
           expect(err).to.not.exist
-          expect(block.key).to.eql(multihash.fromB58String(expectedHash))
-          expect(block.data).to.eql(new Buffer('blorb'))
-          done()
+          ipfs.block.put(blob, (err, block) => {
+            expect(err).to.not.exist
+            expect(block.key).to.eql(multihash.fromB58String(expectedHash))
+            expect(block.data).to.eql(new Buffer('blorb'))
+            done()
+          })
         })
       })
 
diff --git a/src/files.js b/src/files.js
index af1ae188..c844a8c3 100644
--- a/src/files.js
+++ b/src/files.js
@@ -436,10 +436,9 @@ module.exports = (common) => {
             })
         })
 
-        it('errors on invalid key', (done) => {
+        it('errors on invalid key', () => {
           const hash = 'somethingNotMultihash'
-          ipfs.files.get(hash)
-            .then((stream) => {})
+          return ipfs.files.get(hash)
             .catch((err) => {
               expect(err).to.exist
               const errString = err.toString()
@@ -449,7 +448,6 @@ module.exports = (common) => {
               if (errString === 'Error: Invalid Key') {
                 expect(err.toString()).to.contain('Error: Invalid Key')
               }
-              done()
             })
         })
       })
diff --git a/src/object.js b/src/object.js
index 39c71c4c..22711823 100644
--- a/src/object.js
+++ b/src/object.js
@@ -6,6 +6,36 @@
 const expect = require('chai').expect
 const DAGNode = require('ipfs-merkle-dag').DAGNode
 const bs58 = require('bs58')
+const parallel = require('async/parallel')
+const waterfall = require('async/waterfall')
+const promisify = require('promisify-es6')
+
+const checkMultihash = (n1, n2, cb) => {
+  parallel([
+    (cb) => n1.multihash(cb),
+    (cb) => n2.multihash(cb)
+  ], (err, res) => {
+    if (err) {
+      return cb(err)
+    }
+    cb(null, res[0], res[1])
+  })
+}
+const sameMultihash = promisify((n1, n2, cb) => {
+  checkMultihash(n1, n2, (err, h1, h2) => {
+    expect(err).to.not.exist
+    expect(h1).to.be.eql(h2)
+    cb()
+  })
+})
+
+const differentMultihash = promisify((n1, n2, cb) => {
+  checkMultihash(n1, n2, (err, h1, h2) => {
+    expect(err).to.not.exist
+    expect(h1).to.not.be.eql(h2)
+    cb()
+  })
+})
 
 module.exports = (common) => {
   describe('.object', () => {
@@ -29,14 +59,42 @@ module.exports = (common) => {
       common.teardown(done)
     })
 
+    const putAndGet = promisify((putMethod, obj, getMethod, getParams, getOpts, assertions, done) => {
+      if (typeof getOpts === 'function') {
+        done = assertions
+        assertions = getOpts
+        getOpts = undefined
+      }
+
+      waterfall([
+        (cb) => ipfs.object[putMethod](obj, cb),
+        (node, cb) => waterfall([
+          (cb) => getParams(node, cb),
+          (digest, cb) => {
+            if (getOpts) {
+              ipfs.object[getMethod](digest, getOpts, cb)
+            } else {
+              ipfs.object[getMethod](digest, cb)
+            }
+          }
+        ], (err, res) => {
+          expect(err).to.not.exist
+          assertions(node, res, cb)
+        })
+      ], done)
+    })
+
     describe('callback API', () => {
       describe('.new', () => {
         it('no layout', (done) => {
-          ipfs.object.new((err, node) => {
-            expect(err).to.not.exist
-            expect(node.toJSON().Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
-            done()
-          })
+          waterfall([
+            (cb) => ipfs.object.new(cb),
+            (node, cb) => node.toJSON(cb),
+            (json, cb) => {
+              expect(json.Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
+              cb()
+            }
+          ], done)
         })
       })
 
@@ -47,14 +105,16 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(obj, (err, node) => {
-            expect(err).to.not.exist
-            const nodeJSON = node.toJSON()
-            expect(obj.Data).to.deep.equal(nodeJSON.Data)
-            expect(obj.Links).to.deep.equal(nodeJSON.Links)
-            expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
-            done()
-          })
+          waterfall([
+            (cb) => ipfs.object.put(obj, cb),
+            (node, cb) => node.toJSON(cb),
+            (nodeJSON, cb) => {
+              expect(obj.Data).to.deep.equal(nodeJSON.Data)
+              expect(obj.Links).to.deep.equal(nodeJSON.Links)
+              expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
+              cb()
+            }
+          ], done)
         })
 
         it('of json encoded buffer', (done) => {
@@ -70,21 +130,23 @@ module.exports = (common) => {
 
           const buf = new Buffer(JSON.stringify(obj2))
 
-          ipfs.object.put(buf, { enc: 'json' }, (err, node) => {
-            expect(err).to.not.exist
-            const nodeJSON = node.toJSON()
+          waterfall([
+            (cb) => ipfs.object.put(buf, { enc: 'json' }, cb),
+            (node, cb) => node.toJSON((err, nodeJSON) => {
+              expect(err).to.not.exist
 
-            // because js-ipfs-api can't
-            // infer if the returned Data is Buffer or String
-            if (typeof node.data === 'string') {
-              node.data = new Buffer(node.data)
-            }
+              // because js-ipfs-api can't
+              // infer if the returned Data is Buffer or String
+              if (typeof node.data === 'string') {
+                node.data = new Buffer(node.data)
+              }
 
-            expect(obj.Data).to.deep.equal(node.data)
-            expect(obj.Links).to.deep.equal(nodeJSON.Links)
-            expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
-            done()
-          })
+              expect(obj.Data).to.deep.equal(node.data)
+              expect(obj.Links).to.deep.equal(nodeJSON.Links)
+              expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
+              cb()
+            })
+          ], done)
         })
 
         it('of protobuf encoded buffer', (done) => {
@@ -95,32 +157,31 @@ module.exports = (common) => {
             expect(err).to.not.exist
             expect(dNode.data).to.deep.equal(node.data)
             expect(dNode.links).to.deep.equal(node.links)
-            expect(dNode.multihash()).to.deep.equal(node.multihash())
-            done()
+            sameMultihash(dNode, node, done)
           })
         })
 
         it('of buffer treated as Data field', (done) => {
           const data = new Buffer('Some data')
-          ipfs.object.put(data, (err, node) => {
-            expect(err).to.not.exist
-            const nodeJSON = node.toJSON()
-            expect(data).to.deep.equal(nodeJSON.Data)
-            expect([]).to.deep.equal(nodeJSON.Links)
-            expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
-            done()
-          })
+          waterfall([
+            (cb) => ipfs.object.put(data, cb),
+            (node, cb) => node.toJSON(cb),
+            (nodeJSON, cb) => {
+              expect(data).to.deep.equal(nodeJSON.Data)
+              expect([]).to.deep.equal(nodeJSON.Links)
+              expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
+              cb()
+            }
+          ], done)
         })
 
         it('of DAGNode', (done) => {
           const dNode = new DAGNode(new Buffer('Some data'))
-
           ipfs.object.put(dNode, (err, node) => {
             expect(err).to.not.exist
             expect(dNode.data).to.deep.equal(node.data)
             expect(dNode.links).to.deep.equal(node.links)
-            expect(dNode.multihash()).to.deep.equal(node.multihash())
-            done()
+            sameMultihash(dNode, node, done)
           })
         })
 
@@ -134,19 +195,20 @@ module.exports = (common) => {
         it('DAGNode with some DAGLinks', (done) => {
           const dNode1 = new DAGNode(new Buffer('Some data 1'))
           const dNode2 = new DAGNode(new Buffer('Some data 2'))
-          dNode1.addNodeLink('some-link', dNode2)
 
-          ipfs.object.put(dNode1, (err, node) => {
-            expect(err).to.not.exist
-            expect(dNode1.data).to.deep.equal(node.data)
-            expect(
-              dNode1.links.map((l) => l.toJSON())
-            ).to.deep.equal(
-              node.links.map((l) => l.toJSON())
-            )
-            expect(dNode1.multihash()).to.deep.equal(node.multihash())
-            done()
-          })
+          waterfall([
+            (cb) => dNode1.addNodeLink('some-link', dNode2, cb),
+            (cb) => ipfs.object.put(dNode1, cb),
+            (node, cb) => {
+              expect(dNode1.data).to.deep.equal(node.data)
+              expect(
+                dNode1.links.map((l) => l.toJSON())
+              ).to.deep.equal(
+                node.links.map((l) => l.toJSON())
+              )
+              sameMultihash(dNode1, node, cb)
+            }
+          ], done)
         })
       })
 
@@ -156,44 +218,45 @@ module.exports = (common) => {
             Data: new Buffer('get test object'),
             Links: []
           }
-
-          ipfs.object.put(testObj, (err, node1) => {
-            expect(err).to.not.exist
-
-            ipfs.object.get(node1.multihash(), (err, node2) => {
-              expect(err).to.not.exist
+          putAndGet(
+            'put', testObj,
+            'get', (n, cb) => n.multihash(cb),
+            (node1, node2, cb) => {
               // because js-ipfs-api can't infer if the returned Data is Buffer
               // or String
               if (typeof node2.data === 'string') {
                 node2.data = new Buffer(node2.data)
               }
-              expect(node1.multihash()).to.deep.equal(node2.multihash())
+
               expect(node1.data).to.deep.equal(node2.data)
               expect(node1.links).to.deep.equal(node2.links)
-              done()
-            })
-          })
+              sameMultihash(node1, node2, cb)
+            },
+            done
+          )
         })
 
         it('with multihash (+ links)', (done) => {
           const dNode1 = new DAGNode(new Buffer('Some data 1'))
           const dNode2 = new DAGNode(new Buffer('Some data 2'))
-          dNode1.addNodeLink('some-link', dNode2)
-
-          ipfs.object.put(dNode1, (err, node1) => {
+          dNode1.addNodeLink('some-link', dNode2, (err) => {
             expect(err).to.not.exist
 
-            ipfs.object.get(node1.multihash(), (err, node2) => {
-              expect(err).to.not.exist
-              // because js-ipfs-api can't infer if the returned Data is Buffer
-              // or String
-              if (typeof node2.data === 'string') {
-                node2.data = new Buffer(node2.data)
-              }
-              expect(node1.multihash()).to.deep.equal(node2.multihash())
-              expect(node1.data).to.deep.equal(node2.data)
-              done()
-            })
+            putAndGet(
+              'put', dNode1,
+              'get', (n, cb) => n.multihash(cb),
+              (node1, node2, cb) => {
+                // because js-ipfs-api can't infer if the returned Data is Buffer
+                // or String
+                if (typeof node2.data === 'string') {
+                  node2.data = new Buffer(node2.data)
+                }
+
+                expect(node1.data).to.deep.equal(node2.data)
+                sameMultihash(node1, node2, cb)
+              },
+              done
+            )
           })
         })
 
@@ -203,22 +266,26 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node1) => {
-            expect(err).to.not.exist
-
-            ipfs.object.get(bs58.encode(node1.multihash()), { enc: 'base58' }, (err, node2) => {
+          putAndGet(
+            'put', testObj,
+            'get', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest))
+            }),
+            {enc: 'base58'},
+            (node1, node2, cb) => {
               // because js-ipfs-api can't infer if the returned Data is Buffer
               // or String
               if (typeof node2.data === 'string') {
                 node2.data = new Buffer(node2.data)
               }
-              expect(node1.multihash()).to.deep.equal(node2.multihash())
+
               expect(node1.data).to.deep.equal(node2.data)
               expect(node1.links).to.deep.equal(node2.links)
-              done()
-            })
-          })
+              sameMultihash(node1, node2, cb)
+            },
+            done
+          )
         })
 
         it('with multihash base58 encoded toString', (done) => {
@@ -226,23 +293,26 @@ module.exports = (common) => {
             Data: new Buffer('get test object'),
             Links: []
           }
-
-          ipfs.object.put(testObj, (err, node1) => {
-            expect(err).to.not.exist
-
-            ipfs.object.get(bs58.encode(node1.multihash()).toString(), { enc: 'base58' }, (err, node2) => {
+          putAndGet(
+            'put', testObj,
+            'get', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest).toString())
+            }),
+            {enc: 'base58'},
+            (node1, node2, cb) => {
               // because js-ipfs-api can't infer if the returned Data is Buffer
               // or String
               if (typeof node2.data === 'string') {
                 node2.data = new Buffer(node2.data)
               }
-              expect(node1.multihash()).to.deep.equal(node2.multihash())
+
               expect(node1.data).to.deep.equal(node2.data)
               expect(node1.links).to.deep.equal(node2.links)
-              done()
-            })
-          })
+              sameMultihash(node1, node2, cb)
+            },
+            done
+          )
         })
       })
 
@@ -253,20 +323,21 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.data(node.multihash(), (err, data) => {
-              expect(err).to.not.exist
+          putAndGet(
+            'put', testObj,
+            'data', (n, cb) => n.multihash(cb),
+            (node, data, cb) => {
               // because js-ipfs-api can't infer
               // if the returned Data is Buffer or String
               if (typeof data === 'string') {
                 data = new Buffer(data)
               }
+
               expect(node.data).to.deep.equal(data)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
 
         it('with multihash base58 encoded', (done) => {
@@ -275,20 +346,24 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.data(bs58.encode(node.multihash()), { enc: 'base58' }, (err, data) => {
+          putAndGet(
+            'put', testObj,
+            'data', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest))
+            }),
+            {enc: 'base58'},
+            (node, data, cb) => {
               // because js-ipfs-api can't infer
               // if the returned Data is Buffer or String
               if (typeof data === 'string') {
                 data = new Buffer(data)
               }
               expect(node.data).to.deep.equal(data)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
 
         it('with multihash base58 encoded toString', (done) => {
@@ -297,20 +372,24 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.data(bs58.encode(node.multihash()).toString(), { enc: 'base58' }, (err, data) => {
+          putAndGet(
+            'put', testObj,
+            'data', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest).toString())
+            }),
+            {enc: 'base58'},
+            (node, data, cb) => {
               // because js-ipfs-api can't infer if the returned Data is Buffer
               // or String
               if (typeof data === 'string') {
                 data = new Buffer(data)
               }
               expect(node.data).to.deep.equal(data)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
       })
 
@@ -321,30 +400,32 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.links(node.multihash(), (err, links) => {
-              expect(err).to.not.exist
+          putAndGet(
+            'put', testObj,
+            'links', (n, cb) => n.multihash(cb),
+            (node, links, cb) => {
               expect(node.links).to.deep.equal(links)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
 
         it('with multihash (+ links)', (done) => {
           const dNode1 = new DAGNode(new Buffer('Some data 1'))
           const dNode2 = new DAGNode(new Buffer('Some data 2'))
-          dNode1.addNodeLink('some-link', dNode2)
-
-          ipfs.object.put(dNode1, (err, node) => {
+          dNode1.addNodeLink('some-link', dNode2, (err) => {
             expect(err).to.not.exist
 
-            ipfs.object.links(node.multihash(), (err, links) => {
-              expect(err).to.not.exist
-              expect(node.links[0].toJSON()).to.deep.equal(links[0].toJSON())
-              done()
-            })
+            putAndGet(
+              'put', dNode1,
+              'links', (n, cb) => n.multihash(cb),
+              (node, links, cb) => {
+                expect(node.links[0].toJSON()).to.deep.equal(links[0].toJSON())
+                cb()
+              },
+              done
+            )
           })
         })
 
@@ -354,15 +435,19 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.links(bs58.encode(node.multihash()), { enc: 'base58' }, (err, links) => {
+          putAndGet(
+            'put', testObj,
+            'links', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest))
+            }),
+            {enc: 'base58'},
+            (node, links, cb) => {
               expect(node.links).to.deep.equal(links)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
 
         it('with multihash base58 encoded toString', (done) => {
@@ -371,15 +456,19 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.links(bs58.encode(node.multihash()).toString(), { enc: 'base58' }, (err, links) => {
+          putAndGet(
+            'put', testObj,
+            'links', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest).toString())
+            }),
+            {enc: 'base58'},
+            (node, links, cb) => {
               expect(node.links).to.deep.equal(links)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
       })
 
@@ -390,11 +479,10 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.stat(node.multihash(), (err, stats) => {
-              expect(err).to.not.exist
+          putAndGet(
+            'put', testObj,
+            'stat', (n, cb) => n.multihash(cb),
+            (node, stats, cb) => {
               const expected = {
                 Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ',
                 NumLinks: 0,
@@ -404,32 +492,34 @@ module.exports = (common) => {
                 CumulativeSize: 17
               }
               expect(expected).to.deep.equal(stats)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
 
         it('with multihash (+ Links)', (done) => {
           const dNode1 = new DAGNode(new Buffer('Some data 1'))
           const dNode2 = new DAGNode(new Buffer('Some data 2'))
-          dNode1.addNodeLink('some-link', dNode2)
-
-          ipfs.object.put(dNode1, (err, node) => {
+          dNode1.addNodeLink('some-link', dNode2, (err) => {
             expect(err).to.not.exist
-
-            ipfs.object.stat(node.multihash(), (err, stats) => {
-              expect(err).to.not.exist
-              const expected = {
-                Hash: 'QmPR7W4kaADkAo4GKEVVPQN81EDUFCHJtqejQZ5dEG7pBC',
-                NumLinks: 1,
-                BlockSize: 64,
-                LinksSize: 53,
-                DataSize: 11,
-                CumulativeSize: 77
-              }
-              expect(expected).to.deep.equal(stats)
-              done()
-            })
+            putAndGet(
+              'put', dNode1,
+              'stat', (n, cb) => n.multihash(cb),
+              (node, stats, cb) => {
+                const expected = {
+                  Hash: 'QmPR7W4kaADkAo4GKEVVPQN81EDUFCHJtqejQZ5dEG7pBC',
+                  NumLinks: 1,
+                  BlockSize: 64,
+                  LinksSize: 53,
+                  DataSize: 11,
+                  CumulativeSize: 77
+                }
+                expect(expected).to.deep.equal(stats)
+                cb()
+              },
+              done
+            )
           })
         })
 
@@ -439,11 +529,14 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.stat(bs58.encode(node.multihash()), { enc: 'base58' }, (err, stats) => {
+          putAndGet(
+            'put', testObj,
+            'stat', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest))
+            }),
+            {enc: 'base58'},
+            (node, stats, cb) => {
               const expected = {
                 Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ',
                 NumLinks: 0,
@@ -453,9 +546,10 @@ module.exports = (common) => {
                 CumulativeSize: 17
               }
               expect(expected).to.deep.equal(stats)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
 
         it('with multihash base58 encoded toString', (done) => {
@@ -464,11 +558,14 @@ module.exports = (common) => {
             Links: []
           }
 
-          ipfs.object.put(testObj, (err, node) => {
-            expect(err).to.not.exist
-
-            ipfs.object.stat(bs58.encode(node.multihash()).toString(), { enc: 'base58' }, (err, stats) => {
+          putAndGet(
+            'put', testObj,
+            'stat', (n, cb) => n.multihash((err, digest) => {
               expect(err).to.not.exist
+              cb(null, bs58.encode(digest).toString())
+            }),
+            {enc: 'base58'},
+            (node, stats, cb) => {
               const expected = {
                 Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ',
                 NumLinks: 0,
@@ -478,9 +575,10 @@ module.exports = (common) => {
                 CumulativeSize: 17
               }
               expect(expected).to.deep.equal(stats)
-              done()
-            })
-          })
+              cb()
+            },
+            done
+          )
         })
       })
 
@@ -506,42 +604,42 @@ module.exports = (common) => {
           const dNode2 = new DAGNode(new Buffer('some other node'))
           // note: we need to put the linked obj, otherwise IPFS won't timeout
           // cause it needs the node to get its size
-          ipfs.object.put(dNode2, (err) => {
-            expect(err).to.not.exist
-            dNode1.addNodeLink('link-to-node', dNode2)
 
-            ipfs.object.patch.addLink(testNode.multihash(), dNode1.links[0], (err, node3) => {
-              expect(err).to.not.exist
-              expect(dNode1.multihash()).to.deep.equal(node3.multihash())
+          waterfall([
+            (cb) => ipfs.object.put(dNode2, cb),
+            (n, cb) => dNode1.addNodeLink('link-to-node', dNode2, cb),
+            (cb) => testNode.multihash(cb),
+            (digest, cb) => ipfs.object.patch.addLink(digest, dNode1.links[0], cb),
+            (node3, cb) => {
               testNodeWithLink = node3
               testLink = dNode1.links[0]
-              done()
-            })
-          })
+              sameMultihash(dNode1, node3, cb)
+            }
+          ], done)
         })
 
         it('.rmLink', (done) => {
-          ipfs.object.patch.rmLink(testNodeWithLink.multihash(), testLink, (err, node) => {
-            expect(err).to.not.exist
-            expect(node.multihash()).to.deep.equal(testNode.multihash())
-            done()
-          })
+          waterfall([
+            (cb) => testNodeWithLink.multihash(cb),
+            (digest, cb) => ipfs.object.patch.rmLink(digest, testLink, cb),
+            (node, cb) => sameMultihash(node, testNode, cb)
+          ], done)
         })
 
         it('.appendData', (done) => {
-          ipfs.object.patch.appendData(testNode.multihash(), new Buffer('append'), (err, node) => {
-            expect(err).to.not.exist
-            expect(node.multihash()).to.not.deep.equal(testNode.multihash())
-            done()
-          })
+          waterfall([
+            (cb) => testNode.multihash(cb),
+            (digest, cb) => ipfs.object.patch.appendData(digest, new Buffer('append'), cb),
+            (node, cb) => differentMultihash(node, testNode, cb)
+          ], done)
         })
 
         it('.setData', (done) => {
-          ipfs.object.patch.appendData(testNode.multihash(), new Buffer('set'), (err, node) => {
-            expect(err).to.not.exist
-            expect(node.multihash()).to.not.deep.equal(testNode.multihash())
-            done()
-          })
+          waterfall([
+            (cb) => testNode.multihash(cb),
+            (digest, cb) => ipfs.object.patch.setData(digest, new Buffer('set'), cb),
+            (node, cb) => differentMultihash(node, testNode, cb)
+          ], done)
         })
       })
     })
@@ -549,8 +647,9 @@ module.exports = (common) => {
     describe('promise API', () => {
       it('object.new', () => {
         return ipfs.object.new()
-          .then((node) => {
-            expect(node.toJSON().Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
+          .then((node) => promisify(node.toJSON, {context: node})())
+          .then((json) => {
+            expect(json.Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
           })
       })
 
@@ -561,8 +660,8 @@ module.exports = (common) => {
         }
 
         return ipfs.object.put(obj)
-          .then((node) => {
-            const nodeJSON = node.toJSON()
+          .then((node) => promisify(node.toJSON, {context: node})())
+          .then((nodeJSON) => {
             expect(obj.Data).to.deep.equal(nodeJSON.Data)
             expect(obj.Links).to.deep.equal(nodeJSON.Links)
             expect(nodeJSON.Hash).to.equal('QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK')
@@ -577,16 +676,18 @@ module.exports = (common) => {
 
         return ipfs.object.put(testObj)
           .then((node1) => {
-            return ipfs.object.get(node1.multihash())
+            return promisify(node1.multihash, {context: node1})()
+              .then((digest) => ipfs.object.get(digest))
               .then((node2) => {
                 // because js-ipfs-api can't infer if the returned Data is Buffer
                 // or String
                 if (typeof node2.data === 'string') {
                   node2.data = new Buffer(node2.data)
                 }
-                expect(node1.multihash()).to.deep.equal(node2.multihash())
+
                 expect(node1.data).to.deep.equal(node2.data)
                 expect(node1.links).to.deep.equal(node2.links)
+                return sameMultihash(node1, node2)
               })
           })
       })
@@ -599,7 +700,8 @@ module.exports = (common) => {
 
         return ipfs.object.put(testObj)
           .then((node) => {
-            return ipfs.object.data(node.multihash())
+            return promisify(node.multihash, {context: node})()
+              .then((digest) => ipfs.object.data(digest))
               .then((data) => {
                 // because js-ipfs-api can't infer
                 // if the returned Data is Buffer or String
@@ -618,9 +720,8 @@ module.exports = (common) => {
         }
 
         return ipfs.object.put(testObj)
-          .then((node) => {
-            return ipfs.object.stat(node.multihash())
-          })
+          .then((node) => promisify(node.multihash, {context: node})())
+          .then((digest) => ipfs.object.stat(digest))
           .then((stats) => {
             const expected = {
               Hash: 'QmNggDXca24S6cMPEYHZjeuc4QRmofkRrAEqVL3Ms2sdJZ',
@@ -642,10 +743,11 @@ module.exports = (common) => {
 
         return ipfs.object.put(testObj)
           .then((node) => {
-            return ipfs.object.links(node.multihash())
-              .then((links) => {
-                expect(node.links).to.deep.equal(links)
-              })
+            return promisify(node.multihash, {context: node})()
+            .then((digest) => ipfs.object.links(digest))
+            .then((links) => {
+              expect(node.links).to.deep.equal(links)
+            })
           })
       })
 
@@ -653,6 +755,7 @@ module.exports = (common) => {
         let testNode
         let testNodeWithLink
         let testLink
+        let testNodeHash
 
         before(() => {
           const obj = {
@@ -663,6 +766,9 @@ module.exports = (common) => {
           return ipfs.object.put(obj)
             .then((node) => {
               testNode = node
+              return promisify(testNode.multihash, {context: testNode})()
+            }).then((digest) => {
+              testNodeHash = digest
             })
         })
 
@@ -672,41 +778,34 @@ module.exports = (common) => {
           // note: we need to put the linked obj, otherwise IPFS won't timeout
           // cause it needs the node to get its size
           return ipfs.object.put(dNode2)
+            .then(() => promisify(dNode1.addNodeLink, {context: dNode1})('link-to-node', dNode2))
             .then(() => {
-              dNode1.addNodeLink('link-to-node', dNode2)
-
               return ipfs.object.patch
-                .addLink(testNode.multihash(), dNode1.links[0])
+                .addLink(testNodeHash, dNode1.links[0])
                 .then((node3) => {
-                  expect(dNode1.multihash()).to.deep.equal(node3.multihash())
                   testNodeWithLink = node3
                   testLink = dNode1.links[0]
+                  return sameMultihash(dNode1, node3)
                 })
             })
         })
 
         it('.rmLink', () => {
-          return ipfs.object.patch
-            .rmLink(testNodeWithLink.multihash(), testLink)
-            .then((node) => {
-              expect(node.multihash()).to.deep.equal(testNode.multihash())
-            })
+          return promisify(testNodeWithLink.multihash, {context: testNodeWithLink})()
+            .then((digest) => ipfs.object.patch.rmLink(digest, testLink))
+            .then((node) => sameMultihash(node, testNode))
         })
 
         it('.appendData', () => {
           return ipfs.object.patch
-            .appendData(testNode.multihash(), new Buffer('append'))
-            .then((node) => {
-              expect(node.multihash()).to.not.deep.equal(testNode.multihash())
-            })
+            .appendData(testNodeHash, new Buffer('append'))
+            .then((node) => differentMultihash(node, testNode))
         })
 
         it('.setData', () => {
           return ipfs.object.patch
-            .appendData(testNode.multihash(), new Buffer('set'))
-            .then((node) => {
-              expect(node.multihash()).to.not.deep.equal(testNode.multihash())
-            })
+            .appendData(testNodeHash, new Buffer('set'))
+            .then((node) => differentMultihash(node, testNode))
         })
       })
     })