Comparing version 0.2.4 to 0.3.0
77
dev.js
const nearlib = require('./'); | ||
const sendJson = require('./internal/send-json'); | ||
const localStorageAccountIdKey = 'dev_near_user'; | ||
const storageAccountIdKey = 'dev_near_user'; | ||
// This key will only be available on dev/test environments. Do not rely on it for anything that runs on mainnet. | ||
const devKey = new nearlib.KeyPair( | ||
'22skMptHjFWNyuEWY22ftn2AbLPSYpmYwGJRGwpNHbTV', | ||
'2wyRcSwSuHtRVmkMCGjPwnzZmQLeXLzLLyED1NDMt4BjnKgQL6tF85yBx6Jr26D2dUNeC716RBoTxntVHsegogYw' | ||
); | ||
const devAccountName = 'alice.near'; | ||
module.exports = { | ||
getConfig: async function() { | ||
return JSON.parse(decodeURIComponent(getCookie('fiddleConfig'))); | ||
return JSON.parse(decodeURIComponent(getCookie('fiddleConfig'))) || {}; | ||
}, | ||
connect: async function(nodeUrl) { | ||
const studioConfig = await this.getConfig(); | ||
const near = nearlib.Near.createDefaultConfig(nodeUrl || studioConfig.nodeUrl); | ||
await this.getOrCreateDevUser(near); | ||
return near; | ||
/** | ||
* Create a connection which can perform operations on behalf of a given account. | ||
* @param {object} options object to pass named parameters. | ||
* @param {Object} options.nodeUrl specifies node url. accountId specifies account id. key_pair is the key pair for account | ||
* @param {boolean} options.useDevAccount specify to use development account to create accounts / deploy contracts. Should be used only on TestNet. | ||
* @param {string} options.accountId account ID to use. | ||
*/ | ||
connect: async function(options = {}) { | ||
if (options.useDevAccount) { | ||
options.accountId = devAccountName; | ||
options.key = devKey; | ||
} | ||
const keyStore = (options.deps && options.deps.keyStore) || new nearlib.BrowserLocalStorageKeystore(); | ||
const nodeUrl = options.nodeUrl || (await this.getConfig()).nodeUrl || 'http://localhost:3030'; | ||
const nearClient = new nearlib.NearClient( | ||
new nearlib.SimpleKeyStoreSigner(keyStore), new nearlib.LocalNodeConnection(nodeUrl)); | ||
this.near = new nearlib.Near(nearClient); | ||
if (options.accountId) { | ||
keyStore.setKey(options.accountId, options.key); | ||
} else { | ||
await this.getOrCreateDevUser(options.deps); | ||
} | ||
return this.near; | ||
}, | ||
getOrCreateDevUser: async function (near) { | ||
let tempUserAccountId = window.localStorage.getItem(localStorageAccountIdKey); | ||
if (tempUserAccountId) { | ||
// Make sure the user actually exists and recreate it if it doesn't | ||
const accountLib = new nearlib.Account(near.nearClient); | ||
getOrCreateDevUser: async function (deps = {}) { | ||
const storage = deps.storage || window.storage; | ||
let tempUserAccountId = storage.getItem(storageAccountIdKey); | ||
const localKeyStore = deps.keyStore || new nearlib.BrowserLocalStorageKeystore(); | ||
const accountKey = await localKeyStore.getKey(tempUserAccountId); | ||
if (tempUserAccountId && accountKey) { | ||
// Make sure the user actually exists with valid keys and recreate it if it doesn't | ||
const accountLib = new nearlib.Account(this.near.nearClient); | ||
try { | ||
@@ -32,19 +61,25 @@ await accountLib.viewAccount(tempUserAccountId); | ||
const nearConfig = await this.getConfig(); | ||
await sendJson('POST', `${nearConfig.baseUrl}/account`, { | ||
newAccountId: tempUserAccountId, | ||
newAccountPublicKey: keypair.getPublicKey() | ||
}); | ||
const keyStore = new nearlib.BrowserLocalStorageKeystore(); | ||
keyStore.setKey(tempUserAccountId, keypair); | ||
window.localStorage.setItem(localStorageAccountIdKey, tempUserAccountId); | ||
const createAccount = deps.createAccount ? deps.createAccount : | ||
async (accountId, newAccountPublicKey) => | ||
createAccountWithContractHelper(nearConfig, accountId, newAccountPublicKey); | ||
await createAccount(tempUserAccountId, keypair.getPublicKey()); | ||
localKeyStore.setKey(tempUserAccountId, keypair); | ||
storage.setItem(storageAccountIdKey, tempUserAccountId); | ||
return tempUserAccountId; | ||
}, | ||
get myAccountId() { | ||
return window.localStorage.getItem(localStorageAccountIdKey); | ||
return window.storage.getItem(storageAccountIdKey); | ||
} | ||
}; | ||
async function createAccountWithContractHelper(nearConfig, newAccountId, publicKey) { | ||
return await sendJson('POST', `${nearConfig.baseUrl}/account`, { | ||
newAccountId: newAccountId, | ||
newAccountPublicKey: publicKey | ||
}); | ||
} | ||
function getCookie(name) { | ||
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); | ||
return v ? v[2] : null; | ||
} | ||
} |
@@ -1,2 +0,1 @@ | ||
const bs58 = require('bs58'); | ||
const createError = require('http-errors'); | ||
@@ -3,0 +2,0 @@ |
{ | ||
"name": "nearlib", | ||
"description": "Javascript library to interact with near blockchain", | ||
"version": "0.2.4", | ||
"version": "0.3.0", | ||
"repository": { | ||
@@ -22,3 +22,3 @@ "type": "git", | ||
"documentation": "^9.1.1", | ||
"eslint": "^5.12.1", | ||
"eslint": "^5.14.0", | ||
"jest": "^23.6.0", | ||
@@ -25,0 +25,0 @@ "uglifyify": "^5.0.1" |
@@ -16,4 +16,8 @@ /** | ||
} | ||
async clear() { | ||
this.keys = {}; | ||
} | ||
} | ||
module.exports = InMemoryKeyStore; |
@@ -1,17 +0,23 @@ | ||
const { Account, SimpleKeyStoreSigner, InMemoryKeyStore, KeyPair, LocalNodeConnection, NearClient, Near } = require('../'); | ||
const { Account, KeyPair, Near, InMemoryKeyStore } = require('../'); | ||
const dev = require('../dev'); | ||
const fs = require('fs'); | ||
const aliceAccountName = 'alice.near'; | ||
const aliceKey = new KeyPair( | ||
'22skMptHjFWNyuEWY22ftn2AbLPSYpmYwGJRGwpNHbTV', | ||
'2wyRcSwSuHtRVmkMCGjPwnzZmQLeXLzLLyED1NDMt4BjnKgQL6tF85yBx6Jr26D2dUNeC716RBoTxntVHsegogYw' | ||
); | ||
const test_key_store = new InMemoryKeyStore(); | ||
const simple_key_store_signer = new SimpleKeyStoreSigner(test_key_store); | ||
test_key_store.setKey(aliceAccountName, aliceKey); | ||
const localNodeConnection = new LocalNodeConnection('http://localhost:3030'); | ||
const nearClient = new NearClient(simple_key_store_signer, localNodeConnection); | ||
const account = new Account(nearClient); | ||
const nearjs = new Near(nearClient); | ||
// every new account has this codehash | ||
const newAccountCodeHash = 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn'; | ||
const storageAccountIdKey = 'dev_near_user'; | ||
let nearjs; | ||
let account; | ||
let keyStore; | ||
beforeAll(async () => { | ||
keyStore = new InMemoryKeyStore(); | ||
const storage = createFakeStorage(); | ||
nearjs = await dev.connect({ | ||
nodeUrl: 'http://localhost:3030', | ||
useDevAccount: true, | ||
deps: { keyStore, storage }, | ||
}); | ||
account = new Account(nearjs.nearClient); | ||
}); | ||
test('test creating default config', async () => { | ||
@@ -22,2 +28,69 @@ // Make sure createDefaultConfig doesn't crash. | ||
describe('dev connect', () => { | ||
let deps; | ||
beforeEach(async () => { | ||
const keyStore = new InMemoryKeyStore(); | ||
const storage = createFakeStorage(); | ||
deps = { | ||
keyStore, | ||
storage, | ||
createAccount: (async (newAccountName, newAccountPublicKey) => { | ||
const createAccountResponse = await account.createAccount(newAccountName, newAccountPublicKey, 1, aliceAccountName); | ||
await nearjs.waitForTransactionResult(createAccountResponse); | ||
}) | ||
}; | ||
}); | ||
test('test dev connect with no account creates a new account', async () => { | ||
await dev.connect({deps}); | ||
expect(Object.keys(deps.keyStore.keys).length).toEqual(1); | ||
const newAccountId = Object.keys(deps.keyStore.keys)[0]; | ||
const viewAccountResponse = await account.viewAccount(newAccountId); | ||
const newAccountKeyPair = await deps.keyStore.getKey(newAccountId); | ||
expect(newAccountKeyPair).toBeTruthy(); | ||
const expectedAccount = { | ||
nonce: 0, | ||
account_id: newAccountId, | ||
amount: 1, | ||
code_hash: newAccountCodeHash, | ||
stake: 0, | ||
}; | ||
expect(viewAccountResponse).toEqual(expectedAccount); | ||
expect(deps.storage.getItem(storageAccountIdKey)).toEqual(newAccountId); | ||
}); | ||
test('test dev connect with invalid account in storage creates a new account', async () => { | ||
// set up invalid account id in local storage | ||
deps.storage.setItem(storageAccountIdKey, await generateUniqueString('invalid')); | ||
await dev.connect({deps}); | ||
expect(Object.keys(deps.keyStore.keys).length).toEqual(1); | ||
const newAccountId = Object.keys(deps.keyStore.keys)[0]; | ||
const viewAccountResponse = await account.viewAccount(newAccountId); | ||
const newAccountKeyPair = await deps.keyStore.getKey(newAccountId); | ||
expect(newAccountKeyPair).toBeTruthy(); | ||
const expectedAccount = { | ||
nonce: 0, | ||
account_id: newAccountId, | ||
amount: 1, | ||
code_hash: newAccountCodeHash, | ||
stake: 0, | ||
}; | ||
expect(viewAccountResponse).toEqual(expectedAccount); | ||
expect(deps.storage.getItem(storageAccountIdKey)).toEqual(newAccountId); | ||
}); | ||
test('test dev connect with valid account but no keys', async () => { | ||
// setup: connect with dev, but rmemove keys afterwards! | ||
deps.storage.setItem(storageAccountIdKey, await generateUniqueString('invalid')); | ||
await dev.connect({deps}); | ||
expect(Object.keys(deps.keyStore.keys).length).toEqual(1); | ||
const newAccountId = Object.keys(deps.keyStore.keys)[0]; | ||
expect(deps.storage.getItem(storageAccountIdKey)).toEqual(newAccountId); | ||
await deps.keyStore.clear(); | ||
await dev.connect({deps}); | ||
// we are expecting account to be recreated! | ||
expect(deps.storage.getItem(storageAccountIdKey)).not.toEqual(newAccountId); | ||
}); | ||
}); | ||
test('view pre-defined account works and returns correct name', async () => { | ||
@@ -39,3 +112,3 @@ // We do not want to check the other properties of this account since we create other accounts | ||
amount: 1, | ||
code_hash: 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn', | ||
code_hash: newAccountCodeHash, | ||
stake: 0, | ||
@@ -61,3 +134,3 @@ }; | ||
amount: amount, | ||
code_hash: 'GKot5hBsd81kMupNCXHaqbhv3huEbxAFMLnpcX2hniwn', | ||
code_hash: newAccountCodeHash, | ||
stake: 0, | ||
@@ -86,3 +159,3 @@ }; | ||
await nearjs.waitForTransactionResult(createAccountResponse); | ||
test_key_store.setKey(contractName, keyWithRandomSeed); | ||
keyStore.setKey(contractName, keyWithRandomSeed); | ||
const data = [...fs.readFileSync('../tests/hello.wasm')]; | ||
@@ -139,8 +212,7 @@ await nearjs.waitForTransactionResult( | ||
// test that load contract works and we can make calls afterwards | ||
const options = { | ||
const contract = await nearjs.loadContract(contractName, { | ||
viewMethods: ['hello', 'getValue'], | ||
changeMethods: ['setValue'], | ||
sender: aliceAccountName | ||
}; | ||
const contract = await nearjs.loadContract(contractName, options); | ||
sender: aliceAccountName, | ||
}); | ||
const helloResult = await contract.hello(args); | ||
@@ -177,1 +249,19 @@ expect(helloResult).toEqual('hello trex'); | ||
}; | ||
const createFakeStorage = function() { | ||
let store = {}; | ||
return { | ||
getItem: function(key) { | ||
return store[key]; | ||
}, | ||
setItem: function(key, value) { | ||
store[key] = value.toString(); | ||
}, | ||
clear: function() { | ||
store = {}; | ||
}, | ||
removeItem: function(key) { | ||
delete store[key]; | ||
} | ||
}; | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
664519
13931