fpriv / factom-harmony-connect-js-sdk Goto Github PK
View Code? Open in Web Editor NEWA Software Development Kit for implementing Harmony Connect
License: MIT License
A Software Development Kit for implementing Harmony Connect
License: MIT License
These 3 lines at https://github.com/FactomProject/factom-harmony-connect-js-sdk/blob/master/sample-app/assets/js/main.js#L4-L6 ...
$('#simulateBtn').html('Simulating...');
$('#simulateBtn').addClass('spinning');
$('#simulateBtn').attr('disabled','disabled');
...can be simplified to...
$('#simulateBtn')
.html('Simulating...')
.addClass('spinning')
.attr('disabled','disabled');
Here is the response as it is returned from the API alone:
...and here is that same response as it comes back from the SDK method, searchChains()
:
"chainSearchResult": {
"0": {
"stage": "replicated",
"href": "/v1/chains/ce80b403fb3ebc71c81cec4dcf375f183baeb7c70f73d80f99db7cdd79108d4a",
"external_ids": ["U2lnbmVkQ2hhaW4=", "AQ==", "MTcxZTU4NTE0NTFjZTZmMmQ5NzMwYzE1MzdkYTQzNzVmZWI0NDI4NzBkODM1YzU0YTFiY2E4ZmZhN2UyYmRhNw==", "aWRwdWIyU3JFWWFjN1lRZDZ4UUpLSHQ3aE1XVGd6QkxEZXlQWXNLOWp3SnlReDViZlp2Y3hFOQ==", "/Fopv1Mocy7tpqRcLWI8E4o6hBF25Hh8bGdmW0PhgpUcHGrXlFg7Hf9cOmh/WaKxWabKGtG2jkIM/tfitUFUCw==", "MjAxOS0wMi0xMlQyMjowMTo0NS4zMTBa", "Tm90YXJ5U2ltdWxhdGlvbg==", "Q3VzdG9tZXJDaGFpbg==", "Y3VzdDEyMw=="],
"created_at": null,
"chain_id": "ce80b403fb3ebc71c81cec4dcf375f183baeb7c70f73d80f99db7cdd79108d4a"
},
"dblock": {
"height": 121115,
"keymr": "0fc6fc4c48b45b0d82638717d2b7de327ec5f2eea485c0c5e41999f6f0f5349e",
"href": "/v1/dblocks/0fc6fc4c48b45b0d82638717d2b7de327ec5f2eea485c0c5e41999f6f0f5349e"
}
},
@hieumt2 I believe you already know about this, but just wanted to create a GIthub issue to make it easier to track and discuss.
Maybe I am misunderstanding how this works (in which case we should probably update the docs to clarify), but...
const chainInfo = await factomConnectSDK.chains.getChainInfo({
chainId: '71c013c0fd9dc287735518b63ac283d51798b44391985f2ab21f542b288c5211'
});
const firstEntryInfo = await chainInfo.getFirstEntry();
gives me this in the console:
TypeError: chainInfo.getFirstEntry is not a function
at module.exports (/Users/DoronHomeFolder/Sites/factom/factom-harmony-connect-js-sdk/sample-app/testMethods.js:127:42)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
TypeError: chainInfo.getFirstEntry is not a function
at module.exports (/Users/DoronHomeFolder/Sites/factom/factom-harmony-connect-js-sdk/sample-app/testMethods.js:127:42)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
Creating a chain using this method call...
const createChainResponse = await factomConnectSDK.chains.createChain({
externalIds: ['doron', '44', 'texas'],
content: 'I am an awesome guy'
});
...and then getting that info back using this method call...
const getAllChainsResponse = await factomConnectSDK.chains.getAllChains();
...is returning...
"chainInfo": {
"chain": {
"data": {
"stage": "factom",
"external_ids": ["doron", "0x3434", "texas"],
"entries": {
"href": "/v1/chains/6e43a3f0711792d42834dc0e6b5da28bfa74ac22915f4662c7d27c4ec527f77a/entries"
},
"eblock": {
"keymr": "8dea3aca60f7caf377b78684360c34ac8b1caee98b7e4027ccaf3d38befc6f27",
"href": "/v1/eblocks/8dea3aca60f7caf377b78684360c34ac8b1caee98b7e4027ccaf3d38befc6f27"
},
"dblock": {
"height": 121115,
"keymr": "0fc6fc4c48b45b0d82638717d2b7de327ec5f2eea485c0c5e41999f6f0f5349e",
"href": "/v1/dblocks/0fc6fc4c48b45b0d82638717d2b7de327ec5f2eea485c0c5e41999f6f0f5349e"
},
"created_at": "2019-02-08T17:19:00.000000Z",
"content": "I am an awesome guy",
"chain_id": "6e43a3f0711792d42834dc0e6b5da28bfa74ac22915f4662c7d27c4ec527f77a"
}
},
"status": "not_signed/invalid_chain_format"
},
The 2nd value in the external_ids
property, "0x3434"
should be "44"
?
NOTE: This bug does not seem to apply to all stringified numbers, and in fact, 44 is the only number I am seeing coming back in the wrong format. If I try, say, "144"
or "111"
, then those array items come back in the correct format, just like they were specified when the chain was created via the SDK.
Getting this for the following methods:
factomConnectSDK.chains.getAllChains()
factomConnectSDK.chains.chainInfo()
factomConnectSDK.entries.getEntryInfo()
(also seen it come back as "3434"
when it was last item in array)Executing the following method...
const chainSearchResult = await factomConnectSDK.chains.searchChains({
externalIds: ['doron']
});
...returns this result which was created with "doron"
as one of the array items...
"chainSearchResult": {
"offset": 0,
"limit": 15,
"data": {
"0": {
"stage": "factom",
"href": "/v1/chains/6e43a3f0711792d42834dc0e6b5da28bfa74ac22915f4662c7d27c4ec527f77a",
"external_ids": ["ZG9yb24=", "NDQ=", "dGV4YXM="],
"created_at": "2019-02-08T17:19:00.000000Z",
"chain_id": "6e43a3f0711792d42834dc0e6b5da28bfa74ac22915f4662c7d27c4ec527f77a"
},
"dblock": {
"height": 121115,
"keymr": "0fc6fc4c48b45b0d82638717d2b7de327ec5f2eea485c0c5e41999f6f0f5349e",
"href": "/v1/dblocks/0fc6fc4c48b45b0d82638717d2b7de327ec5f2eea485c0c5e41999f6f0f5349e"
}
},
"count": 1
},
Also, please make sure that the return format of the external_ids
is included in the unit tests.
UPDATE (5/16/19): After doing some more research, we've decided NOT to put overriding properties on a separate clientOverrides
object. Instead, we will simply be allowing developers to place those properties on the top level of the parameter object for each method. So we would be "merging-left" any of the optional property values (code example below has been updated).
There are certain instances where we'd like to allow the user to specify override parameters that were set in the instantiation of the SDK. Right now, the parameters we're looking to allow to be overridden are:
appId
appKey
baseUrl
automaticSigning
To add optional overrides, we are going to add a new property named clientOverrides
, which will be an object containing the aforementioned properties (appId
, appKey
, etc). Simply add to clientOverrides
any properties that are part of the instantiated SDK class that you'd like to override the override.
Example:
await factomConnectSDK.chains.get({
chainId: "4b9532c79d53ab22b85951b4a5853f81c2682132b3c810a95128c30401cd1e58",
accessToken: {
appId: "YOUR APP ID",
appKey: "YOUR APP KEY"
},
baseUrl: "YOUR API URL"
});
const createChainResponse = await factomConnectSDK.chains.create({
signerPrivateKey: keyToSign.private_key,
signerChainId: identityChainId,
externalIds: ["NotarySimulation", "CustomerChain", "cust123"],
content:
"This chain represents a notary service's customer in the NotarySimulation, a sample implementation provided as part of the Factom Harmony SDKs. Learn more here: https://docs.harmony.factom.com/docs/sdks-clients",
automaticSigning: false
});
const chainInfo = await factomConnectSDK.chains.getChainInfo({
chainId: '71c013c0fd9dc287735518b63ac283d51798b44391985f2ab21f542b288c5211'
});
const lastEntryInfo = await chainInfo.getlastEntry();
...gets me in the console...
TypeError: chainInfo.getlastEntry is not a function
at module.exports (/Users/DoronHomeFolder/Sites/factom/factom-harmony-connect-js-sdk/sample-app/testMethods.js:127:47)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
(not sure why it's formatting the URLs like this, hopefully makes sense)
Running this...
const chainInfo = await factomConnectSDK.chains.getChainInfo({
chainId: '71c013c0fd9dc287735518b63ac283d51798b44391985f2ab21f542b288c5211'
});
const entriesList = await chainInfo.getEntries();
Results in this error in the console...
TypeError: chainInfo.getEntries is not a function
at module.exports (/Users/DoronHomeFolder/Sites/factom/factom-harmony-connect-js-sdk/sample-app/testMethods.js:126:41)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
TypeError: chainInfo.getEntries is not a function
at module.exports (/Users/DoronHomeFolder/Sites/factom/factom-harmony-connect-js-sdk/sample-app/testMethods.js:126:41)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
The docs indicate that there is an SDK method named getEntries()
, but the odd thing is that the documentation doesn't indicate that chainId
is a required or optional parameter, nor does it specify that getEntries()
needs to be called on an instance of an existing chain object.
Getting the following when running npm run build
.
Tried updating all npm packages and running npm audit fix
, issue w/developer has been open for 6 months now: emn178/js-sha256#18.
Options:
Best practice is usually to have standard interfaces for each request type that match up with the REST interface (GET, CREATE, DESTROY, etc) with more specific variants for the less commonly used behavior.
For example, if i'm doing FactomSDK.indentity.createIdentity()
, I already know it's an identity by it being encapsulated by Identity
. so a more useful name for that would be FactomSDK.identity.create()
.
Each Resource method should have its own methods ending simply in get()
or create()
. The only non-REST generic methods would be search()
, getFirst()
and getLast()
.
So for example:
First, we instantiate our chain by doing, instead of...
const myChain = factomConnectSDK.chain({
chainId: '123456'
});
...we do...
const myChain = FactomSDK.chain.get({
chainId: '123456'
});
...so no more Chain
constructor for the user to think about, we roll it all into the .get()
method.
From there, continuing the pattern, we change this...
myChain.createEntry({
...
})
...to be...
myChain.entries.create({
...
});
Going one level deeper, this...
myChain.getFirstEntry();
...becomes...
myChain.entry.getFirst() // defaults to `true` for checking validation
myChain.entry.getFirst({
signatureValidation: false
}) // doesn't check validation
AND...
const myEntries = myChain.entries.get();
const myEntrySearchResults = myEntries.searchEntriesOfChain({
...
})
...becomes...
const myEntries = myChain.entries.get();
const myEntrySearchResults = myEntries.search({
...
})
Hello @hieumt2, is this code in the repo just for debugging on your end: https://github.com/FactomProject/factom-harmony-connect-js-sdk/blob/master/sample-app/simulateNotary.js#L8-L11 ? I noticed that the npm package necessary to execute this code was missing from the package.json
, so maybe it wasn't intended to stay?
I ask because when I pulled down the latest from master and then tried running the sample app starting the simulation process, the api call timed out and gave me the errors below. However, once I removed that code, everything seems to work perfectly.
Can you please confirm that the globalTunnel
code needs to remain there, and if so, perhaps you can clarify why I might be getting this error.
{ Error: tunneling socket could not be established, cause=connect ETIMEDOUT 10.133.93.63:8080
at ClientRequest.onError (/Users/DoronHomeFolder/Sites/factom/factom-harmony-connect-js-sdk/node_modules/tunnel/lib/tunnel.js:180:17)
at Object.onceWrapper (events.js:315:30)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
code: 'ECONNRESET',
config:
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
app_id: 'aabe7d81',
app_key: '502a5c77f8f600b9ec32e94fbe008f11',
'User-Agent': 'axios/0.18.0',
'Content-Length': 255 },
method: 'post',
url: 'https://durable.sandbox.harmony.factom.com/v1/identities',
data: '{"name":["Tm90YXJ5U2ltdWxhdGlvbg==","MjAxOS0wMi0xM1QxNzo0ODoyMi42NDJa"],"keys":["idpub2Cktw6EgcBVMHMXmfcCyTHndcFvG7fJKyBpy3sTYcdTmdTuKya","idpub2JegfdBQBnqbXGKMMD89v8N81e4DpvERHWTJp6zvWaoAVi8Jnj","idpub2SrEYac7YQd6xQJKHt7hMWTgzBLDeyPYsK9jwJyQx5bfZvcxE9"]}' },
request:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
domain: null,
_events:
{ response: [Function: handleResponse],
error: [Function: handleRequestError] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'https:',
path: '/v1/identities',
method: 'post',
headers: [Object],
agent: undefined,
auth: undefined,
hostname: 'durable.sandbox.harmony.factom.com',
port: null,
nativeProtocols: [Object],
pathname: '/v1/identities' },
_ended: false,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 255,
_requestBodyBuffers: [ [Object] ],
_onNativeResponse: [Function],
_currentRequest:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [Array],
outputEncodings: [Array],
outputCallbacks: [Array],
outputSize: 531,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: false,
_headerSent: true,
socket: null,
connection: null,
_header: 'POST /v1/identities HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json\r\napp_id: aabe7d81\r\napp_key: 502a5c77f8f600b9ec32e94fbe008f11\r\nUser-Agent: axios/0.18.0\r\nContent-Length: 255\r\nHost: durable.sandbox.harmony.factom.com\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/v1/identities',
_ended: false,
res: null,
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Circular],
[Symbol(outHeadersKey)]: [Object] },
_currentUrl: 'https://durable.sandbox.harmony.factom.com/v1/identities' },
response: undefined }
Please make the following changes:
So comment should read:
// Init factom sdk with your app_id and app_key, which can be found or generated at https://account.factom.com
So, chains.js
=> Chains.js
, identity.js
=> Identity.js
, etc etc etc...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.