SDKs
The official JavaScript SDK builds sign-in URLs and sign links and calls the Hivesigner API for you. For Python, community libraries exist. Any other language can call the REST API directly.
JavaScript SDK
The SDK is the npm package hivesigner. Its source is at https://github.com/ecency/hivesigner-sdk. It is written in TypeScript and ships its types.
Version 4 needs Node.js 18 or later, because it uses the built-in fetch. In browsers it needs ES2017 or later. Where no global fetch exists, add a polyfill before you use the SDK. On an older Node.js, stay on version 3.
Install
npm install hivesigner
For a page without a build step, load the browser bundle. It defines a global hivesigner:
<script src="https://cdn.jsdelivr.net/npm/hivesigner@4/lib/hivesigner.min.js"></script>
Create a client
import { Client } from 'hivesigner';
const client = new Client({
app: 'CLIENT_ID',
callbackURL: 'REDIRECT_URI',
scope: ['posting'],
});
| Option | Meaning |
|---|---|
app |
Your app account, sent as client_id. |
callbackURL |
Where Hivesigner sends the user back. It must be one of your app's callbacks, character for character (a plain-http loopback callback may differ in host and port, see Callbacks). |
scope |
A list, joined with commas into the scope parameter. See Scopes. |
responseType |
'code' for the code flow. Leave it out for the token flow. |
accessToken |
The user's access token, when you already have one. |
apiURL |
The origin of the API. The SDK adds /api/ to it. The default is https://hivesigner.com. |
setApp, setCallbackURL, setScope, setAccessToken, removeAccessToken and setApiURL change the client later. Each one returns the client.
Sign the user in
getLoginURL(state, account) returns the sign-in URL:
const url = client.getLoginURL('STATE');
// https://hivesigner.com/oauth2/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=posting&state=STATE
statecomes back to your callback unchanged. Use it to tie the answer to the request.accountis optional: a username. Hivesigner selects that account when it is on the device and ignores it otherwise.
In a browser, client.login({ state: 'STATE' }) sends the user to the same URL, without an account.
In the token flow, your callback receives access_token, expires_in and username. Give the token to the client:
client.setAccessToken('ACCESS_TOKEN');
The SDK has no method for the code flow's exchange. Your server posts the code and the client secret to the API itself, as Exchange the code shows.
Get the user
const me = await client.me();
// { user, _id, name, account, scope, user_metadata }
account is the user's Hive account as the chain returns it. scope lists what the token allows.
Broadcast
broadcast(operations) sends operations to the API, which broadcasts them for the user. The API accepts only posting operations that the token's user authors: vote, comment, delete_comment, comment_options, custom_json with posting authority, claim_reward_balance and account_update2 for profile metadata. See What broadcast accepts.
await client.broadcast([
['vote', { voter: 'USERNAME', author: 'AUTHOR', permlink: 'PERMLINK', weight: 10000 }],
]);
Name the user in each operation. The API does not replace __signer.
These helpers build one operation each and call broadcast:
| Method | Broadcasts |
|---|---|
vote(voter, author, permlink, weight) |
vote. weight runs from -10000 to 10000 (100%). |
comment(parentAuthor, parentPermlink, author, permlink, title, body, jsonMetadata) |
comment. For a new post, parentAuthor is ''. jsonMetadata can be an object: the SDK turns it into a string. |
deleteComment(author, permlink) |
delete_comment |
customJson(requiredAuths, requiredPostingAuths, id, json) |
custom_json. Pass [] as requiredAuths and ['USERNAME'] as requiredPostingAuths. json is a string. |
reblog(account, author, permlink) |
custom_json with id follow, reblogging the post |
follow(follower, following) |
custom_json with id follow, what: ['blog'] |
unfollow(unfollower, unfollowing) |
custom_json with id follow, what: [] |
ignore(follower, following) |
custom_json with id follow, what: ['ignore'] (mute) |
claimRewardBalance(account, rewardHive, rewardHbd, rewardVests) |
claim_reward_balance. Amounts are strings such as '0.000 HIVE', '0.000 HBD' and '1.000000 VESTS'. |
updateUserMetadata() is deprecated. To change a user's profile, broadcast account_update2 with a new posting_json_metadata.
Log out
revokeToken() is the SDK's log-out call. It sends the token to the API's revoke endpoint and then removes it from the client. When the call rejects, call removeAccessToken() yourself. Also delete the token wherever your app stored it.
To end your app's access for good, the user removes it at https://hivesigner.com/authorized-apps. See See and remove an app's access.
Sign links
sendOperation(op, params), sendOperations(ops, params) and sendTransaction(tx, params) return a https://hivesigner.com/sign/... link. params takes callback, no_broadcast and signer. See Sign links.
import { sendOperation } from 'hivesigner';
const link = sendOperation(
['transfer', { from: '__signer', to: 'RECIPIENT', amount: '1.000 HIVE', memo: 'MEMO' }],
{ callback: 'https://YOUR_APP/paid' },
);
In TypeScript the types require the third argument: pass undefined to get the link back.
In a browser, pass a function as the third argument to open the link in a new tab instead. The function is not called and nothing is returned. Call it from a click handler, or the browser may block the new tab and the call throws.
Promises and callbacks
me, broadcast, the helpers and revokeToken return a promise. Pass a function as the last argument to use a callback instead. It receives (error, result).
// Promise
try {
const result = await client.vote('USERNAME', 'AUTHOR', 'PERMLINK', 10000);
} catch (error) {
console.error(error.error, error.error_description);
}
// Callback
client.vote('USERNAME', 'AUTHOR', 'PERMLINK', 10000, (error, result) => {
if (error) console.error(error.error, error.error_description);
});
When the API answers with an error, the promise rejects with the API's error body, { error, error_description }. With a callback, that body is the error argument. When the answer is not JSON, it rejects with the parse error.
Python
These libraries come from the community. Their authors maintain them, not the Hivesigner team. Check them against the REST API before you rely on them.
| Library | Author |
|---|---|
| hivesigner-python-client: https://github.com/emre/hivesigner-python-client | emrebeyler |
beem, module beem.hivesigner: https://beem.readthedocs.io/en/latest/beem.hivesigner.html |
holger80 |