hivesigner 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -2
- package/lib/client.d.ts +19 -2
- package/lib/hivesigner.min.js +1 -1
- package/lib/index.d.ts +4 -0
- package/lib/index.js +67 -9
- package/lib/pkce.d.ts +16 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/login-options.interface.d.ts +2 -0
- package/lib/types/token-response.interface.d.ts +8 -0
- package/package.json +4 -1
- package/.claude/settings.local.json +0 -12
- package/.eslintignore +0 -3
- package/.eslintrc.js +0 -16
- package/CLAUDE.md +0 -142
- package/docs/CNAME +0 -1
- package/docs/index.html +0 -221
- package/jest.config.js +0 -10
- package/rollup.config.js +0 -13
- package/src/client.spec.ts +0 -453
- package/src/client.ts +0 -318
- package/src/consts/api-url.const.ts +0 -1
- package/src/consts/base-url.const.ts +0 -1
- package/src/consts/beta-url.const.ts +0 -1
- package/src/consts/index.ts +0 -3
- package/src/default-import.spec.ts +0 -10
- package/src/factories/index.ts +0 -1
- package/src/factories/initialize.factory.spec.ts +0 -9
- package/src/factories/initialize.factory.ts +0 -7
- package/src/index.ts +0 -16
- package/src/methods/index.ts +0 -4
- package/src/methods/send-operation.method.spec.ts +0 -47
- package/src/methods/send-operation.method.ts +0 -14
- package/src/methods/send-operations.method.spec.ts +0 -47
- package/src/methods/send-operations.method.ts +0 -14
- package/src/methods/send-transaction.method.spec.ts +0 -47
- package/src/methods/send-transaction.method.ts +0 -14
- package/src/methods/sign.method.spec.ts +0 -60
- package/src/methods/sign.method.ts +0 -22
- package/src/modules-import.spec.ts +0 -11
- package/src/require-import.spec.js +0 -16
- package/src/require-import.spec.ts +0 -10
- package/src/types/callback-function.type.ts +0 -1
- package/src/types/client-config.interface.ts +0 -8
- package/src/types/hive.types.ts +0 -12
- package/src/types/index.ts +0 -6
- package/src/types/login-options.interface.ts +0 -3
- package/src/types/send-response.type.ts +0 -1
- package/src/types/sign-errors.interface.ts +0 -4
- package/src/utilities/index.ts +0 -1
- package/src/utilities/is-browser.util.ts +0 -3
- package/tsconfig.json +0 -17
- package/webpack.config.js +0 -33
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# HiveSigner SDK
|
|
6
6
|
|
|
7
|
-
The official HiveSigner JavaScript SDK, written in Typescript. Library supports both callback and promise functions. Learn more about integration: https://
|
|
7
|
+
The official HiveSigner JavaScript SDK, written in Typescript. Library supports both callback and promise functions. Learn more about integration: https://hivesigner.com/docs.
|
|
8
8
|
|
|
9
9
|
## Upgrading to v4
|
|
10
10
|
|
|
@@ -49,7 +49,7 @@ or
|
|
|
49
49
|
|
|
50
50
|
For general information about HiveSigner and setting up your app you can checkout the developer documentation.
|
|
51
51
|
|
|
52
|
-
**[Developers documentation](https://hivesigner.com/
|
|
52
|
+
**[Developers documentation](https://hivesigner.com/docs)**
|
|
53
53
|
|
|
54
54
|
## SDK methods
|
|
55
55
|
|
|
@@ -93,6 +93,20 @@ After logging in, HiveSigner will redirect the user to the "redirect_uri" specif
|
|
|
93
93
|
- __expires_in__: The number of seconds until the access token expires.
|
|
94
94
|
- __username__: The username of the current user.
|
|
95
95
|
|
|
96
|
+
### Mobile and desktop apps: PKCE
|
|
97
|
+
An app that cannot keep a client secret (a mobile or desktop app) uses the code flow with PKCE. It may then use its own scheme as the callback, such as `myapp://callback`, registered on its app account.
|
|
98
|
+
```js
|
|
99
|
+
import { Client, createPkcePair } from 'hivesigner';
|
|
100
|
+
|
|
101
|
+
const client = new Client({ app: 'myapp', callbackURL: 'myapp://callback', responseType: 'code', scope: ['posting'] });
|
|
102
|
+
|
|
103
|
+
const { codeVerifier, codeChallenge } = await createPkcePair(); // keep codeVerifier in memory
|
|
104
|
+
const link = client.getLoginURL(state, undefined, { codeChallenge });
|
|
105
|
+
// open link, then on myapp://callback?code=CODE&state=STATE:
|
|
106
|
+
const { access_token, username } = await client.exchangeCode(code, codeVerifier);
|
|
107
|
+
```
|
|
108
|
+
The code can be exchanged once, within 10 minutes, and only with the verifier. A native app gets no refresh token. A server can pass its client secret as the third argument of `exchangeCode`. `createPkcePair` needs Web Crypto: Node.js 20+ or a modern browser. In React Native, add a `crypto.getRandomValues` and `crypto.subtle` polyfill, or make the pair with a native library and pass the challenge to `getLoginURL`. The rest of the SDK still runs on Node.js 18. Full guide: https://hivesigner.com/docs/pkce
|
|
109
|
+
|
|
96
110
|
### Get user profile
|
|
97
111
|
Once a user is logged in to your app you can call the following method to get the details of their account:
|
|
98
112
|
```
|
package/lib/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CallbackFunction, ClientConfig, LoginOptions, Operation, SendResponse } from './types';
|
|
1
|
+
import { CallbackFunction, ClientConfig, LoginOptions, Operation, SendResponse, TokenResponse } from './types';
|
|
2
2
|
export declare class Client {
|
|
3
3
|
apiURL: string;
|
|
4
4
|
app: string;
|
|
@@ -14,8 +14,25 @@ export declare class Client {
|
|
|
14
14
|
setAccessToken(accessToken: string): this;
|
|
15
15
|
removeAccessToken(): this;
|
|
16
16
|
setScope(scope: string[]): this;
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* The authorize URL. Pass `options.codeChallenge` (from createPkcePair) to
|
|
19
|
+
* protect a code flow sign-in with PKCE, which a native app needs for a
|
|
20
|
+
* custom scheme callback such as `myapp://callback`.
|
|
21
|
+
*/
|
|
22
|
+
getLoginURL(state: string, account?: string, options?: {
|
|
23
|
+
codeChallenge?: string;
|
|
24
|
+
}): string;
|
|
18
25
|
login(options: LoginOptions): void;
|
|
26
|
+
/**
|
|
27
|
+
* Exchange a code for tokens at /api/oauth2/token. With PKCE send the
|
|
28
|
+
* verifier; a native app sends no secret and gets no refresh token. A
|
|
29
|
+
* server may pass its client secret as well.
|
|
30
|
+
*
|
|
31
|
+
* Sent WITHOUT the Authorization header: the API reads that header before
|
|
32
|
+
* the body, so a token this client already holds would be read instead of
|
|
33
|
+
* the code.
|
|
34
|
+
*/
|
|
35
|
+
exchangeCode(code: string, codeVerifier?: string, clientSecret?: string): Promise<TokenResponse>;
|
|
19
36
|
me(): Promise<SendResponse>;
|
|
20
37
|
me(cb: CallbackFunction): Promise<SendResponse>;
|
|
21
38
|
decode(memo: string): Promise<SendResponse>;
|
package/lib/hivesigner.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var hivesigner;(()=>{"use strict";var e={536(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.encodeMsg=t.encodeOps=t.encodeOp=t.encodeTx=t.resolveCallback=t.resolveTransaction=t.decode=void 0;var n=o(160);"undefined"==typeof btoa&&(o.g.btoa=function(e){return Buffer.from(e,"binary").toString("base64")}),"undefined"==typeof atob&&(o.g.atob=function(e){return Buffer.from(e,"base64").toString("binary")});var r={"/":"_",_:"/","+":"-","-":"+","=":".",".":"="},s=function(e){return btoa(unescape(encodeURIComponent(e))).replace(/(\+|\/|=)/g,function(e){return r[e]})},i=function(e){return decodeURIComponent(escape(atob(e.replace(/(-|_|\.)/g,function(e){return r[e]}))))};t.decode=function(e){var t=e.slice(0,5),o=new n(e.replace(/^hive:/,"http:"));if("hive:"!==t)throw new Error("Invalid protocol, expected 'hive:' got '"+t+"'");if("sign"!==o.host)throw new Error("Invalid action, expected 'sign' got '"+o.host+"'");var r,s,a=o.pathname.split("/").slice(1),c=a[0],l=a[1];try{r=JSON.parse(i(l))}catch(e){throw e.message="Invalid payload: "+e.message,e}switch(c){case"tx":case"msg":s=r;break;case"op":case"ops":s={ref_block_num:"__ref_block_num",ref_block_prefix:"__ref_block_prefix",expiration:"__expiration",extensions:[],operations:"ops"===c?r:[r]};break;default:throw new Error("Invalid signing action '"+c+"'")}var u=Object.fromEntries(o.query.substring(1).split("&").filter(Boolean).map(function(e){var t=e.split("="),o=t[0],n=t[1],r=void 0===n?"":n;return[decodeURIComponent(o),decodeURIComponent(r)]})),p={};return u.cb&&(p.callback=i(u.cb)),void 0!==u.nb&&(p.no_broadcast=!0),u.a&&(p.authority=u.a),u.s&&(p.signer=u.s),{tx:s,params:p}};var a=/(__(ref_block_(num|prefix)|expiration|signer))/g;t.resolveTransaction=function(e,t,o){var n=t.signer||o.preferred_signer;if(!o.signers.includes(n))throw new Error("Signer '"+n+"' not available");var r={__ref_block_num:o.ref_block_num,__ref_block_prefix:o.ref_block_prefix,__expiration:o.expiration,__signer:n},s=function(e){var t=typeof e;switch("object"===t&&Array.isArray(e)?t="array":null===e&&(t="null"),t){case"string":return e.replace(a,function(e){return r[e]});case"array":return e.map(s);case"object":for(var o={},n=0,i=Object.entries(e);n<i.length;n++){var c=i[n],l=c[0],u=c[1];o[l]=s(u)}return o;default:return e}};return{signer:n,tx:s(e)}};var c=/({{(sig|id|block|txn|data)}})/g;function l(e){var t=[];return e.no_broadcast&&t.push("nb="),e.signer&&t.push("s="+e.signer),e.callback&&t.push("cb="+s(e.callback)),e.authority&&t.push("a="+e.authority),t.length?"?"+t.join("&"):""}function u(e){return s(JSON.stringify(e,null,0))}t.resolveCallback=function(e,t){return e.replace(c,function(e,o,n){return t[n]||""})},t.encodeTx=function(e,t){return void 0===t&&(t={}),"hive://sign/tx/"+u(e)+l(t)},t.encodeOp=function(e,t){return void 0===t&&(t={}),"hive://sign/op/"+u(e)+l(t)},t.encodeOps=function(e,t){return void 0===t&&(t={}),"hive://sign/ops/"+u(e)+l(t)},t.encodeMsg=function(e,t){return void 0===t&&(t={}),"hive://sign/msg/"+u(e)+l(t)}},992(e,t){var o=Object.prototype.hasOwnProperty;function n(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function r(e){try{return encodeURIComponent(e)}catch(e){return null}}t.stringify=function(e,t){t=t||"";var n,s,i=[];for(s in"string"!=typeof t&&(t="?"),e)if(o.call(e,s)){if((n=e[s])||null!=n&&!isNaN(n)||(n=""),s=r(s),n=r(n),null===s||null===n)continue;i.push(s+"="+n)}return i.length?t+i.join("&"):""},t.parse=function(e){for(var t,o=/([^=?#&]+)=?([^&]*)/g,r={};t=o.exec(e);){var s=n(t[1]),i=n(t[2]);null===s||null===i||s in r||(r[s]=i)}return r}},63(e){e.exports=function(e,t){if(t=t.split(":")[0],!(e=+e))return!1;switch(t){case"http":case"ws":return 80!==e;case"https":case"wss":return 443!==e;case"ftp":return 21!==e;case"gopher":return 70!==e;case"file":return!1}return 0!==e}},469(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.Client=void 0;const n=o(629),r=o(779);t.Client=class{constructor(e){this.apiURL=e.apiURL||n.API_URL,this.app=e.app,this.callbackURL=e.callbackURL,this.accessToken=e.accessToken,this.scope=e.scope,this.responseType=e.responseType}setBaseURL(){return console.warn('The function "setBaseUrl" is deprecated, the base URL is always "https://hivesigner.com", you can only change the API URL with "setApiURL"'),this}setApiURL(e){return this.apiURL=e,this}setApp(e){return this.app=e,this}setCallbackURL(e){return this.callbackURL=e,this}setAccessToken(e){return this.accessToken=e,this}removeAccessToken(){return delete this.accessToken,this}setScope(e){return this.scope=e,this}getLoginURL(e,t){const o=encodeURIComponent(this.callbackURL);let r=`${n.BASE_URL}/oauth2/authorize?client_id=${this.app}&redirect_uri=${o}`;return"code"===this.responseType&&(r+=`&response_type=${this.responseType}`),this.scope&&(r+=`&scope=${this.scope.join(",")}`),e&&(r+=`&state=${encodeURIComponent(e)}`),t&&(r+=`&account=${encodeURIComponent(t)}`),r}login(e){(0,r.isBrowser)()&&(window.location=this.getLoginURL(e.state))}me(e){return this.send("me","POST",{},e)}decode(e,t){return this.send("decode","POST",{memo:e},t)}vote(e,t,o,n,r){const s={voter:e,author:t,permlink:o,weight:n};return this.broadcast([["vote",s]],r)}comment(e,t,o,n,r,s,i,a){let c=i;"string"!=typeof i&&(c=JSON.stringify(i));const l={parent_author:e,parent_permlink:t,author:o,permlink:n,title:r,body:s,json_metadata:c};return this.broadcast([["comment",l]],a)}deleteComment(e,t,o){const n={author:e,permlink:t};return this.broadcast([["delete_comment",n]],o)}customJson(e,t,o,n,r){const s={required_auths:e,required_posting_auths:t,id:o,json:n};return this.broadcast([["custom_json",s]],r)}reblog(e,t,o,n){const r=["reblog",{account:e,author:t,permlink:o}];return this.customJson([],[e],"follow",JSON.stringify(r),n)}follow(e,t,o){const n=["follow",{follower:e,following:t,what:["blog"]}];return this.customJson([],[e],"follow",JSON.stringify(n),o)}unfollow(e,t,o){const n=["follow",{follower:e,following:t,what:[]}];return this.customJson([],[e],"follow",JSON.stringify(n),o)}ignore(e,t,o){const n=["follow",{follower:e,following:t,what:["ignore"]}];return this.customJson([],[e],"follow",JSON.stringify(n),o)}claimRewardBalance(e,t,o,n,r){const s={account:e,reward_hive:t,reward_hbd:o,reward_vests:n};return this.broadcast([["claim_reward_balance",s]],r)}async revokeToken(e){return await this.send("oauth2/token/revoke","POST",{token:this.accessToken},e),this.removeAccessToken()}updateUserMetadata(e={},t){return console.warn('The function "updateUserMetadata" is deprecated.'),this.send("me","PUT",{user_metadata:e},t)}async send(e,t,o,n){const r=`${this.apiURL}/api/${e}`;if(!n)return this.makeRequest(r,t,o);try{return n(null,await this.makeRequest(r,t,o))}catch(e){return n(e,null)}}broadcast(e,t){return this.send("broadcast","POST",{operations:e},t)}async makeRequest(e,t,o){if("function"!=typeof globalThis.fetch)throw new Error("hivesigner: fetch is not available. Node.js 18+ or a modern browser is required. If you are in an older environment, provide a global fetch polyfill.");const n=await globalThis.fetch(e,{method:t,headers:{Accept:"application/json, text/plain, */*","Content-Type":"application/json",Authorization:this.accessToken},body:JSON.stringify(o)}),r=await n.json();if(200!==n.status||r.error)throw r;return r}}},944(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.API_URL=void 0,t.API_URL="https://hivesigner.com"},69(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.BASE_URL=void 0,t.BASE_URL="https://hivesigner.com"},290(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.BETA_URL=void 0,t.BETA_URL="https://hivesigner.com"},629(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(944),t),r(o(69),t),r(o(290),t)},261(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(7),t)},7(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.Initialize=void 0;const n=o(469);t.Initialize=function(e){return console.warn('The function "Initialize" is deprecated, please use the class "Client" instead.'),new n.Client(e)}},440(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(469),t),r(o(49),t),r(o(261),t);const s=o(469),i=o(261),a=o(49);t.default={Client:s.Client,Initialize:i.Initialize,sendTransaction:a.sendTransaction,sendOperations:a.sendOperations,sendOperation:a.sendOperation,sign:a.sign}},49(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(893),t),r(o(640),t),r(o(243),t),r(o(887),t)},640(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sendOperation=void 0;const n=o(629),r=o(536),s=o(779);t.sendOperation=function(e,t,o){const i=(0,r.encodeOp)(e,t).replace("hive://",`${n.BETA_URL}/`);return o&&(0,s.isBrowser)()?window.open(i,"_blank").focus():i}},243(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sendOperations=void 0;const n=o(536),r=o(779),s=o(629);t.sendOperations=function(e,t,o){const i=(0,n.encodeOps)(e,t).replace("hive://",`${s.BETA_URL}/`);return o&&(0,r.isBrowser)()?window.open(i,"_blank").focus():i}},887(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sendTransaction=void 0;const n=o(536),r=o(629),s=o(779);t.sendTransaction=function(e,t,o){const i=(0,n.encodeTx)(e,t).replace("hive://",`${r.BETA_URL}/`);return o&&(0,s.isBrowser)()?window.open(i,"_blank").focus():i}},893(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sign=void 0;const n=o(629);t.sign=function(e,t,o){if(console.warn('The function "sign" is deprecated.'),"string"!=typeof e||"object"!=typeof t||null===t)return{error:"invalid_request",error_description:"Request has an invalid format"};let r=`${n.BASE_URL}/sign/${e}?`;return r+=Object.keys(t).map(e=>`${e}=${encodeURIComponent(t[e])}`).join("&"),r+=o?`&redirect_uri=${encodeURIComponent(o)}`:"",r}},779(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(790),t)},790(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.isBrowser=void 0,t.isBrowser=function(){return"undefined"!=typeof window&&!!window}},160(e,t,o){var n=o(63),r=o(992),s=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,i=/[\n\r\t]/g,a=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,c=/:\d+$/,l=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i,u=/^[a-zA-Z]:/;function p(e){return(e||"").toString().replace(s,"")}var d=[["#","hash"],["?","query"],function(e,t){return v(t.protocol)?e.replace(/\\/g,"/"):e},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d*)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],h={hash:1,query:1};function f(e){var t,n=("undefined"!=typeof window?window:void 0!==o.g?o.g:"undefined"!=typeof self?self:{}).location||{},r={},s=typeof(e=e||n);if("blob:"===e.protocol)r=new g(unescape(e.pathname),{});else if("string"===s)for(t in r=new g(e,{}),h)delete r[t];else if("object"===s){for(t in e)t in h||(r[t]=e[t]);void 0===r.slashes&&(r.slashes=a.test(e.href))}return r}function v(e){return"file:"===e||"ftp:"===e||"http:"===e||"https:"===e||"ws:"===e||"wss:"===e}function b(e,t){e=(e=p(e)).replace(i,""),t=t||{};var o,n=l.exec(e),r=n[1]?n[1].toLowerCase():"",s=!!n[2],a=!!n[3],c=0;return s?a?(o=n[2]+n[3]+n[4],c=n[2].length+n[3].length):(o=n[2]+n[4],c=n[2].length):a?(o=n[3]+n[4],c=n[3].length):o=n[4],"file:"===r?c>=2&&(o=o.slice(2)):v(r)?o=n[4]:r?s&&(o=o.slice(2)):c>=2&&v(t.protocol)&&(o=n[4]),{protocol:r,slashes:s||v(r),slashesCount:c,rest:o}}function g(e,t,o){if(e=(e=p(e)).replace(i,""),!(this instanceof g))return new g(e,t,o);var s,a,c,l,h,_,m=d.slice(),w=typeof t,y=this,O=0;for("object"!==w&&"string"!==w&&(o=t,t=null),o&&"function"!=typeof o&&(o=r.parse),s=!(a=b(e||"",t=f(t))).protocol&&!a.slashes,y.slashes=a.slashes||s&&t.slashes,y.protocol=a.protocol||t.protocol||"",e=a.rest,("file:"===a.protocol&&(2!==a.slashesCount||u.test(e))||!a.slashes&&(a.protocol||a.slashesCount<2||!v(y.protocol)))&&(m[3]=[/(.*)/,"pathname"]);O<m.length;O++)"function"!=typeof(l=m[O])?(c=l[0],_=l[1],c!=c?y[_]=e:"string"==typeof c?~(h="@"===c?e.lastIndexOf(c):e.indexOf(c))&&("number"==typeof l[2]?(y[_]=e.slice(0,h),e=e.slice(h+l[2])):(y[_]=e.slice(h),e=e.slice(0,h))):(h=c.exec(e))&&(y[_]=h[1],e=e.slice(0,h.index)),y[_]=y[_]||s&&l[3]&&t[_]||"",l[4]&&(y[_]=y[_].toLowerCase())):e=l(e,y);o&&(y.query=o(y.query)),s&&t.slashes&&"/"!==y.pathname.charAt(0)&&(""!==y.pathname||""!==t.pathname)&&(y.pathname=function(e,t){if(""===e)return t;for(var o=(t||"/").split("/").slice(0,-1).concat(e.split("/")),n=o.length,r=o[n-1],s=!1,i=0;n--;)"."===o[n]?o.splice(n,1):".."===o[n]?(o.splice(n,1),i++):i&&(0===n&&(s=!0),o.splice(n,1),i--);return s&&o.unshift(""),"."!==r&&".."!==r||o.push(""),o.join("/")}(y.pathname,t.pathname)),"/"!==y.pathname.charAt(0)&&v(y.protocol)&&(y.pathname="/"+y.pathname),n(y.port,y.protocol)||(y.host=y.hostname,y.port=""),y.username=y.password="",y.auth&&(~(h=y.auth.indexOf(":"))?(y.username=y.auth.slice(0,h),y.username=encodeURIComponent(decodeURIComponent(y.username)),y.password=y.auth.slice(h+1),y.password=encodeURIComponent(decodeURIComponent(y.password))):y.username=encodeURIComponent(decodeURIComponent(y.auth)),y.auth=y.password?y.username+":"+y.password:y.username),y.origin="file:"!==y.protocol&&v(y.protocol)&&y.host?y.protocol+"//"+y.host:"null",y.href=y.toString()}g.prototype={set:function(e,t,o){var s=this;switch(e){case"query":"string"==typeof t&&t.length&&(t=(o||r.parse)(t)),s[e]=t;break;case"port":s[e]=t,n(t,s.protocol)?t&&(s.host=s.hostname+":"+t):(s.host=s.hostname,s[e]="");break;case"hostname":s[e]=t,s.port&&(t+=":"+s.port),s.host=t;break;case"host":s[e]=t,c.test(t)?(t=t.split(":"),s.port=t.pop(),s.hostname=t.join(":")):(s.hostname=t,s.port="");break;case"protocol":s.protocol=t.toLowerCase(),s.slashes=!o;break;case"pathname":case"hash":if(t){var i="pathname"===e?"/":"#";s[e]=t.charAt(0)!==i?i+t:t}else s[e]=t;break;case"username":case"password":s[e]=encodeURIComponent(t);break;case"auth":var a=t.indexOf(":");~a?(s.username=t.slice(0,a),s.username=encodeURIComponent(decodeURIComponent(s.username)),s.password=t.slice(a+1),s.password=encodeURIComponent(decodeURIComponent(s.password))):s.username=encodeURIComponent(decodeURIComponent(t))}for(var l=0;l<d.length;l++){var u=d[l];u[4]&&(s[u[1]]=s[u[1]].toLowerCase())}return s.auth=s.password?s.username+":"+s.password:s.username,s.origin="file:"!==s.protocol&&v(s.protocol)&&s.host?s.protocol+"//"+s.host:"null",s.href=s.toString(),s},toString:function(e){e&&"function"==typeof e||(e=r.stringify);var t,o=this,n=o.host,s=o.protocol;s&&":"!==s.charAt(s.length-1)&&(s+=":");var i=s+(o.protocol&&o.slashes||v(o.protocol)?"//":"");return o.username?(i+=o.username,o.password&&(i+=":"+o.password),i+="@"):o.password?(i+=":"+o.password,i+="@"):"file:"!==o.protocol&&v(o.protocol)&&!n&&"/"!==o.pathname&&(i+="@"),(":"===n[n.length-1]||c.test(o.hostname)&&!o.port)&&(n+=":"),i+=n+o.pathname,(t="object"==typeof o.query?e(o.query):o.query)&&(i+="?"!==t.charAt(0)?"?"+t:t),o.hash&&(i+=o.hash),i}},g.extractProtocol=b,g.location=f,g.trimLeft=p,g.qs=r,e.exports=g}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var s=t[n]={exports:{}};return e[n].call(s.exports,s,s.exports,o),s.exports}o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}();var n=o(440);hivesigner=n})();
|
|
1
|
+
var hivesigner;(()=>{"use strict";var e={536(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.encodeMsg=t.encodeOps=t.encodeOp=t.encodeTx=t.resolveCallback=t.resolveTransaction=t.decode=void 0;var n=o(160);"undefined"==typeof btoa&&(o.g.btoa=function(e){return Buffer.from(e,"binary").toString("base64")}),"undefined"==typeof atob&&(o.g.atob=function(e){return Buffer.from(e,"base64").toString("binary")});var r={"/":"_",_:"/","+":"-","-":"+","=":".",".":"="},s=function(e){return btoa(unescape(encodeURIComponent(e))).replace(/(\+|\/|=)/g,function(e){return r[e]})},i=function(e){return decodeURIComponent(escape(atob(e.replace(/(-|_|\.)/g,function(e){return r[e]}))))};t.decode=function(e){var t=e.slice(0,5),o=new n(e.replace(/^hive:/,"http:"));if("hive:"!==t)throw new Error("Invalid protocol, expected 'hive:' got '"+t+"'");if("sign"!==o.host)throw new Error("Invalid action, expected 'sign' got '"+o.host+"'");var r,s,a=o.pathname.split("/").slice(1),c=a[0],l=a[1];try{r=JSON.parse(i(l))}catch(e){throw e.message="Invalid payload: "+e.message,e}switch(c){case"tx":case"msg":s=r;break;case"op":case"ops":s={ref_block_num:"__ref_block_num",ref_block_prefix:"__ref_block_prefix",expiration:"__expiration",extensions:[],operations:"ops"===c?r:[r]};break;default:throw new Error("Invalid signing action '"+c+"'")}var u=Object.fromEntries(o.query.substring(1).split("&").filter(Boolean).map(function(e){var t=e.split("="),o=t[0],n=t[1],r=void 0===n?"":n;return[decodeURIComponent(o),decodeURIComponent(r)]})),p={};return u.cb&&(p.callback=i(u.cb)),void 0!==u.nb&&(p.no_broadcast=!0),u.a&&(p.authority=u.a),u.s&&(p.signer=u.s),{tx:s,params:p}};var a=/(__(ref_block_(num|prefix)|expiration|signer))/g;t.resolveTransaction=function(e,t,o){var n=t.signer||o.preferred_signer;if(!o.signers.includes(n))throw new Error("Signer '"+n+"' not available");var r={__ref_block_num:o.ref_block_num,__ref_block_prefix:o.ref_block_prefix,__expiration:o.expiration,__signer:n},s=function(e){var t=typeof e;switch("object"===t&&Array.isArray(e)?t="array":null===e&&(t="null"),t){case"string":return e.replace(a,function(e){return r[e]});case"array":return e.map(s);case"object":for(var o={},n=0,i=Object.entries(e);n<i.length;n++){var c=i[n],l=c[0],u=c[1];o[l]=s(u)}return o;default:return e}};return{signer:n,tx:s(e)}};var c=/({{(sig|id|block|txn|data)}})/g;function l(e){var t=[];return e.no_broadcast&&t.push("nb="),e.signer&&t.push("s="+e.signer),e.callback&&t.push("cb="+s(e.callback)),e.authority&&t.push("a="+e.authority),t.length?"?"+t.join("&"):""}function u(e){return s(JSON.stringify(e,null,0))}t.resolveCallback=function(e,t){return e.replace(c,function(e,o,n){return t[n]||""})},t.encodeTx=function(e,t){return void 0===t&&(t={}),"hive://sign/tx/"+u(e)+l(t)},t.encodeOp=function(e,t){return void 0===t&&(t={}),"hive://sign/op/"+u(e)+l(t)},t.encodeOps=function(e,t){return void 0===t&&(t={}),"hive://sign/ops/"+u(e)+l(t)},t.encodeMsg=function(e,t){return void 0===t&&(t={}),"hive://sign/msg/"+u(e)+l(t)}},992(e,t){var o=Object.prototype.hasOwnProperty;function n(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function r(e){try{return encodeURIComponent(e)}catch(e){return null}}t.stringify=function(e,t){t=t||"";var n,s,i=[];for(s in"string"!=typeof t&&(t="?"),e)if(o.call(e,s)){if((n=e[s])||null!=n&&!isNaN(n)||(n=""),s=r(s),n=r(n),null===s||null===n)continue;i.push(s+"="+n)}return i.length?t+i.join("&"):""},t.parse=function(e){for(var t,o=/([^=?#&]+)=?([^&]*)/g,r={};t=o.exec(e);){var s=n(t[1]),i=n(t[2]);null===s||null===i||s in r||(r[s]=i)}return r}},63(e){e.exports=function(e,t){if(t=t.split(":")[0],!(e=+e))return!1;switch(t){case"http":case"ws":return 80!==e;case"https":case"wss":return 443!==e;case"ftp":return 21!==e;case"gopher":return 70!==e;case"file":return!1}return 0!==e}},469(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.Client=void 0;const n=o(629),r=o(779);t.Client=class{constructor(e){this.apiURL=e.apiURL||n.API_URL,this.app=e.app,this.callbackURL=e.callbackURL,this.accessToken=e.accessToken,this.scope=e.scope,this.responseType=e.responseType}setBaseURL(){return console.warn('The function "setBaseUrl" is deprecated, the base URL is always "https://hivesigner.com", you can only change the API URL with "setApiURL"'),this}setApiURL(e){return this.apiURL=e,this}setApp(e){return this.app=e,this}setCallbackURL(e){return this.callbackURL=e,this}setAccessToken(e){return this.accessToken=e,this}removeAccessToken(){return delete this.accessToken,this}setScope(e){return this.scope=e,this}getLoginURL(e,t,o={}){const r=encodeURIComponent(this.callbackURL);let s=`${n.BASE_URL}/oauth2/authorize?client_id=${this.app}&redirect_uri=${r}`;return"code"===this.responseType&&(s+=`&response_type=${this.responseType}`),this.scope&&(s+=`&scope=${this.scope.join(",")}`),e&&(s+=`&state=${encodeURIComponent(e)}`),t&&(s+=`&account=${encodeURIComponent(t)}`),o.codeChallenge&&"code"===this.responseType&&(s+=`&code_challenge=${encodeURIComponent(o.codeChallenge)}&code_challenge_method=S256`),s}login(e){(0,r.isBrowser)()&&(window.location=this.getLoginURL(e.state,void 0,{codeChallenge:e.codeChallenge}))}async exchangeCode(e,t,o){const n={code:e};return t&&(n.code_verifier=t),o&&(n.client_secret=o),await this.makeRequest(`${this.apiURL}/api/oauth2/token`,"POST",n,!1)}me(e){return this.send("me","POST",{},e)}decode(e,t){return this.send("decode","POST",{memo:e},t)}vote(e,t,o,n,r){const s={voter:e,author:t,permlink:o,weight:n};return this.broadcast([["vote",s]],r)}comment(e,t,o,n,r,s,i,a){let c=i;"string"!=typeof i&&(c=JSON.stringify(i));const l={parent_author:e,parent_permlink:t,author:o,permlink:n,title:r,body:s,json_metadata:c};return this.broadcast([["comment",l]],a)}deleteComment(e,t,o){const n={author:e,permlink:t};return this.broadcast([["delete_comment",n]],o)}customJson(e,t,o,n,r){const s={required_auths:e,required_posting_auths:t,id:o,json:n};return this.broadcast([["custom_json",s]],r)}reblog(e,t,o,n){const r=["reblog",{account:e,author:t,permlink:o}];return this.customJson([],[e],"follow",JSON.stringify(r),n)}follow(e,t,o){const n=["follow",{follower:e,following:t,what:["blog"]}];return this.customJson([],[e],"follow",JSON.stringify(n),o)}unfollow(e,t,o){const n=["follow",{follower:e,following:t,what:[]}];return this.customJson([],[e],"follow",JSON.stringify(n),o)}ignore(e,t,o){const n=["follow",{follower:e,following:t,what:["ignore"]}];return this.customJson([],[e],"follow",JSON.stringify(n),o)}claimRewardBalance(e,t,o,n,r){const s={account:e,reward_hive:t,reward_hbd:o,reward_vests:n};return this.broadcast([["claim_reward_balance",s]],r)}async revokeToken(e){return await this.send("oauth2/token/revoke","POST",{token:this.accessToken},e),this.removeAccessToken()}updateUserMetadata(e={},t){return console.warn('The function "updateUserMetadata" is deprecated.'),this.send("me","PUT",{user_metadata:e},t)}async send(e,t,o,n){const r=`${this.apiURL}/api/${e}`;if(!n)return this.makeRequest(r,t,o);try{return n(null,await this.makeRequest(r,t,o))}catch(e){return n(e,null)}}broadcast(e,t){return this.send("broadcast","POST",{operations:e},t)}async makeRequest(e,t,o,n=!0){if("function"!=typeof globalThis.fetch)throw new Error("hivesigner: fetch is not available. Node.js 18+ or a modern browser is required. If you are in an older environment, provide a global fetch polyfill.");const r=await globalThis.fetch(e,{method:t,headers:Object.assign({Accept:"application/json, text/plain, */*","Content-Type":"application/json"},n?{Authorization:this.accessToken}:{}),body:JSON.stringify(o)}),s=await r.json();if(200!==r.status||s.error)throw s;return s}}},944(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.API_URL=void 0,t.API_URL="https://hivesigner.com"},69(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.BASE_URL=void 0,t.BASE_URL="https://hivesigner.com"},290(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.BETA_URL=void 0,t.BETA_URL="https://hivesigner.com"},629(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(944),t),r(o(69),t),r(o(290),t)},261(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(7),t)},7(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.Initialize=void 0;const n=o(469);t.Initialize=function(e){return console.warn('The function "Initialize" is deprecated, please use the class "Client" instead.'),new n.Client(e)}},440(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(469),t),r(o(49),t),r(o(261),t),r(o(295),t);const s=o(469),i=o(261),a=o(49),c=o(295);t.default={Client:s.Client,Initialize:i.Initialize,sendTransaction:a.sendTransaction,sendOperations:a.sendOperations,sendOperation:a.sendOperation,sign:a.sign,createPkcePair:c.createPkcePair,pkceChallengeFor:c.pkceChallengeFor}},49(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(893),t),r(o(640),t),r(o(243),t),r(o(887),t)},640(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sendOperation=void 0;const n=o(629),r=o(536),s=o(779);t.sendOperation=function(e,t,o){const i=(0,r.encodeOp)(e,t).replace("hive://",`${n.BETA_URL}/`);return o&&(0,s.isBrowser)()?window.open(i,"_blank").focus():i}},243(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sendOperations=void 0;const n=o(536),r=o(779),s=o(629);t.sendOperations=function(e,t,o){const i=(0,n.encodeOps)(e,t).replace("hive://",`${s.BETA_URL}/`);return o&&(0,r.isBrowser)()?window.open(i,"_blank").focus():i}},887(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sendTransaction=void 0;const n=o(536),r=o(629),s=o(779);t.sendTransaction=function(e,t,o){const i=(0,n.encodeTx)(e,t).replace("hive://",`${r.BETA_URL}/`);return o&&(0,s.isBrowser)()?window.open(i,"_blank").focus():i}},893(e,t,o){Object.defineProperty(t,"__esModule",{value:!0}),t.sign=void 0;const n=o(629);t.sign=function(e,t,o){if(console.warn('The function "sign" is deprecated.'),"string"!=typeof e||"object"!=typeof t||null===t)return{error:"invalid_request",error_description:"Request has an invalid format"};let r=`${n.BASE_URL}/sign/${e}?`;return r+=Object.keys(t).map(e=>`${e}=${encodeURIComponent(t[e])}`).join("&"),r+=o?`&redirect_uri=${encodeURIComponent(o)}`:"",r}},295(e,t){function o(){const e=globalThis.crypto;if(!e||!e.subtle||"function"!=typeof e.getRandomValues)throw new Error("hivesigner: Web Crypto is not available. Node.js 20+ or a modern browser is required for PKCE.");return e}function n(e){let t="";return e.forEach(e=>{t+=String.fromCharCode(e)}),("function"==typeof btoa?btoa(t):Buffer.from(t,"binary").toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function r(e){const t=await o().subtle.digest("SHA-256",(new TextEncoder).encode(e));return n(new Uint8Array(t))}Object.defineProperty(t,"__esModule",{value:!0}),t.createPkcePair=t.pkceChallengeFor=void 0,t.pkceChallengeFor=r,t.createPkcePair=async function(){const e=n(o().getRandomValues(new Uint8Array(32)));return{codeVerifier:e,codeChallenge:await r(e)}}},779(e,t,o){var n=this&&this.__createBinding||(Object.create?function(e,t,o,n){void 0===n&&(n=o);var r=Object.getOwnPropertyDescriptor(t,o);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[o]}}),Object.defineProperty(e,n,r)}:function(e,t,o,n){void 0===n&&(n=o),e[n]=t[o]}),r=this&&this.__exportStar||function(e,t){for(var o in e)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||n(t,e,o)};Object.defineProperty(t,"__esModule",{value:!0}),r(o(790),t)},790(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.isBrowser=void 0,t.isBrowser=function(){return"undefined"!=typeof window&&!!window}},160(e,t,o){var n=o(63),r=o(992),s=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,i=/[\n\r\t]/g,a=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,c=/:\d+$/,l=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i,u=/^[a-zA-Z]:/;function p(e){return(e||"").toString().replace(s,"")}var d=[["#","hash"],["?","query"],function(e,t){return g(t.protocol)?e.replace(/\\/g,"/"):e},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d*)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],h={hash:1,query:1};function f(e){var t,n=("undefined"!=typeof window?window:void 0!==o.g?o.g:"undefined"!=typeof self?self:{}).location||{},r={},s=typeof(e=e||n);if("blob:"===e.protocol)r=new v(unescape(e.pathname),{});else if("string"===s)for(t in r=new v(e,{}),h)delete r[t];else if("object"===s){for(t in e)t in h||(r[t]=e[t]);void 0===r.slashes&&(r.slashes=a.test(e.href))}return r}function g(e){return"file:"===e||"ftp:"===e||"http:"===e||"https:"===e||"ws:"===e||"wss:"===e}function b(e,t){e=(e=p(e)).replace(i,""),t=t||{};var o,n=l.exec(e),r=n[1]?n[1].toLowerCase():"",s=!!n[2],a=!!n[3],c=0;return s?a?(o=n[2]+n[3]+n[4],c=n[2].length+n[3].length):(o=n[2]+n[4],c=n[2].length):a?(o=n[3]+n[4],c=n[3].length):o=n[4],"file:"===r?c>=2&&(o=o.slice(2)):g(r)?o=n[4]:r?s&&(o=o.slice(2)):c>=2&&g(t.protocol)&&(o=n[4]),{protocol:r,slashes:s||g(r),slashesCount:c,rest:o}}function v(e,t,o){if(e=(e=p(e)).replace(i,""),!(this instanceof v))return new v(e,t,o);var s,a,c,l,h,_,m=d.slice(),w=typeof t,y=this,O=0;for("object"!==w&&"string"!==w&&(o=t,t=null),o&&"function"!=typeof o&&(o=r.parse),s=!(a=b(e||"",t=f(t))).protocol&&!a.slashes,y.slashes=a.slashes||s&&t.slashes,y.protocol=a.protocol||t.protocol||"",e=a.rest,("file:"===a.protocol&&(2!==a.slashesCount||u.test(e))||!a.slashes&&(a.protocol||a.slashesCount<2||!g(y.protocol)))&&(m[3]=[/(.*)/,"pathname"]);O<m.length;O++)"function"!=typeof(l=m[O])?(c=l[0],_=l[1],c!=c?y[_]=e:"string"==typeof c?~(h="@"===c?e.lastIndexOf(c):e.indexOf(c))&&("number"==typeof l[2]?(y[_]=e.slice(0,h),e=e.slice(h+l[2])):(y[_]=e.slice(h),e=e.slice(0,h))):(h=c.exec(e))&&(y[_]=h[1],e=e.slice(0,h.index)),y[_]=y[_]||s&&l[3]&&t[_]||"",l[4]&&(y[_]=y[_].toLowerCase())):e=l(e,y);o&&(y.query=o(y.query)),s&&t.slashes&&"/"!==y.pathname.charAt(0)&&(""!==y.pathname||""!==t.pathname)&&(y.pathname=function(e,t){if(""===e)return t;for(var o=(t||"/").split("/").slice(0,-1).concat(e.split("/")),n=o.length,r=o[n-1],s=!1,i=0;n--;)"."===o[n]?o.splice(n,1):".."===o[n]?(o.splice(n,1),i++):i&&(0===n&&(s=!0),o.splice(n,1),i--);return s&&o.unshift(""),"."!==r&&".."!==r||o.push(""),o.join("/")}(y.pathname,t.pathname)),"/"!==y.pathname.charAt(0)&&g(y.protocol)&&(y.pathname="/"+y.pathname),n(y.port,y.protocol)||(y.host=y.hostname,y.port=""),y.username=y.password="",y.auth&&(~(h=y.auth.indexOf(":"))?(y.username=y.auth.slice(0,h),y.username=encodeURIComponent(decodeURIComponent(y.username)),y.password=y.auth.slice(h+1),y.password=encodeURIComponent(decodeURIComponent(y.password))):y.username=encodeURIComponent(decodeURIComponent(y.auth)),y.auth=y.password?y.username+":"+y.password:y.username),y.origin="file:"!==y.protocol&&g(y.protocol)&&y.host?y.protocol+"//"+y.host:"null",y.href=y.toString()}v.prototype={set:function(e,t,o){var s=this;switch(e){case"query":"string"==typeof t&&t.length&&(t=(o||r.parse)(t)),s[e]=t;break;case"port":s[e]=t,n(t,s.protocol)?t&&(s.host=s.hostname+":"+t):(s.host=s.hostname,s[e]="");break;case"hostname":s[e]=t,s.port&&(t+=":"+s.port),s.host=t;break;case"host":s[e]=t,c.test(t)?(t=t.split(":"),s.port=t.pop(),s.hostname=t.join(":")):(s.hostname=t,s.port="");break;case"protocol":s.protocol=t.toLowerCase(),s.slashes=!o;break;case"pathname":case"hash":if(t){var i="pathname"===e?"/":"#";s[e]=t.charAt(0)!==i?i+t:t}else s[e]=t;break;case"username":case"password":s[e]=encodeURIComponent(t);break;case"auth":var a=t.indexOf(":");~a?(s.username=t.slice(0,a),s.username=encodeURIComponent(decodeURIComponent(s.username)),s.password=t.slice(a+1),s.password=encodeURIComponent(decodeURIComponent(s.password))):s.username=encodeURIComponent(decodeURIComponent(t))}for(var l=0;l<d.length;l++){var u=d[l];u[4]&&(s[u[1]]=s[u[1]].toLowerCase())}return s.auth=s.password?s.username+":"+s.password:s.username,s.origin="file:"!==s.protocol&&g(s.protocol)&&s.host?s.protocol+"//"+s.host:"null",s.href=s.toString(),s},toString:function(e){e&&"function"==typeof e||(e=r.stringify);var t,o=this,n=o.host,s=o.protocol;s&&":"!==s.charAt(s.length-1)&&(s+=":");var i=s+(o.protocol&&o.slashes||g(o.protocol)?"//":"");return o.username?(i+=o.username,o.password&&(i+=":"+o.password),i+="@"):o.password?(i+=":"+o.password,i+="@"):"file:"!==o.protocol&&g(o.protocol)&&!n&&"/"!==o.pathname&&(i+="@"),(":"===n[n.length-1]||c.test(o.hostname)&&!o.port)&&(n+=":"),i+=n+o.pathname,(t="object"==typeof o.query?e(o.query):o.query)&&(i+="?"!==t.charAt(0)?"?"+t:t),o.hash&&(i+=o.hash),i}},v.extractProtocol=b,v.location=f,v.trimLeft=p,v.qs=r,e.exports=v}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var s=t[n]={exports:{}};return e[n].call(s.exports,s,s.exports,o),s.exports}o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}();var n=o(440);hivesigner=n})();
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from './client';
|
|
2
2
|
export * from './methods';
|
|
3
3
|
export * from './factories';
|
|
4
|
+
export * from './pkce';
|
|
4
5
|
import { Client } from './client';
|
|
5
6
|
import { Initialize } from './factories';
|
|
6
7
|
import { sendTransaction, sendOperations, sendOperation, sign } from './methods';
|
|
8
|
+
import { createPkcePair, pkceChallengeFor } from './pkce';
|
|
7
9
|
declare const _default: {
|
|
8
10
|
Client: typeof Client;
|
|
9
11
|
Initialize: typeof Initialize;
|
|
@@ -11,5 +13,7 @@ declare const _default: {
|
|
|
11
13
|
sendOperations: typeof sendOperations;
|
|
12
14
|
sendOperation: typeof sendOperation;
|
|
13
15
|
sign: typeof sign;
|
|
16
|
+
createPkcePair: typeof createPkcePair;
|
|
17
|
+
pkceChallengeFor: typeof pkceChallengeFor;
|
|
14
18
|
};
|
|
15
19
|
export default _default;
|
package/lib/index.js
CHANGED
|
@@ -51,7 +51,12 @@ class Client {
|
|
|
51
51
|
this.scope = scope;
|
|
52
52
|
return this;
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
/**
|
|
55
|
+
* The authorize URL. Pass `options.codeChallenge` (from createPkcePair) to
|
|
56
|
+
* protect a code flow sign-in with PKCE, which a native app needs for a
|
|
57
|
+
* custom scheme callback such as `myapp://callback`.
|
|
58
|
+
*/
|
|
59
|
+
getLoginURL(state, account, options = {}) {
|
|
55
60
|
const redirectUri = encodeURIComponent(this.callbackURL);
|
|
56
61
|
let loginURL = `${BASE_URL}/oauth2/authorize?client_id=${this.app}&redirect_uri=${redirectUri}`;
|
|
57
62
|
if (this.responseType === 'code') {
|
|
@@ -66,14 +71,35 @@ class Client {
|
|
|
66
71
|
if (account) {
|
|
67
72
|
loginURL += `&account=${encodeURIComponent(account)}`;
|
|
68
73
|
}
|
|
74
|
+
// PKCE protects a code: the token flow has none, and Hivesigner ignores it there.
|
|
75
|
+
if (options.codeChallenge && this.responseType === 'code') {
|
|
76
|
+
loginURL += `&code_challenge=${encodeURIComponent(options.codeChallenge)}&code_challenge_method=S256`;
|
|
77
|
+
}
|
|
69
78
|
return loginURL;
|
|
70
79
|
}
|
|
71
80
|
login(options) {
|
|
72
81
|
if (isBrowser()) {
|
|
73
82
|
// @ts-ignore
|
|
74
|
-
window.location = this.getLoginURL(options.state);
|
|
83
|
+
window.location = this.getLoginURL(options.state, undefined, { codeChallenge: options.codeChallenge });
|
|
75
84
|
}
|
|
76
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Exchange a code for tokens at /api/oauth2/token. With PKCE send the
|
|
88
|
+
* verifier; a native app sends no secret and gets no refresh token. A
|
|
89
|
+
* server may pass its client secret as well.
|
|
90
|
+
*
|
|
91
|
+
* Sent WITHOUT the Authorization header: the API reads that header before
|
|
92
|
+
* the body, so a token this client already holds would be read instead of
|
|
93
|
+
* the code.
|
|
94
|
+
*/
|
|
95
|
+
async exchangeCode(code, codeVerifier, clientSecret) {
|
|
96
|
+
const body = { code };
|
|
97
|
+
if (codeVerifier)
|
|
98
|
+
body.code_verifier = codeVerifier;
|
|
99
|
+
if (clientSecret)
|
|
100
|
+
body.client_secret = clientSecret;
|
|
101
|
+
return (await this.makeRequest(`${this.apiURL}/api/oauth2/token`, 'POST', body, false));
|
|
102
|
+
}
|
|
77
103
|
me(cb) {
|
|
78
104
|
return this.send('me', 'POST', {}, cb);
|
|
79
105
|
}
|
|
@@ -170,18 +196,14 @@ class Client {
|
|
|
170
196
|
broadcast(operations, cb) {
|
|
171
197
|
return this.send('broadcast', 'POST', { operations }, cb);
|
|
172
198
|
}
|
|
173
|
-
async makeRequest(url, method, body) {
|
|
199
|
+
async makeRequest(url, method, body, withToken = true) {
|
|
174
200
|
if (typeof globalThis.fetch !== 'function') {
|
|
175
201
|
throw new Error('hivesigner: fetch is not available. Node.js 18+ or a modern browser is required. ' +
|
|
176
202
|
'If you are in an older environment, provide a global fetch polyfill.');
|
|
177
203
|
}
|
|
178
204
|
const response = await globalThis.fetch(url, {
|
|
179
205
|
method,
|
|
180
|
-
headers: {
|
|
181
|
-
Accept: 'application/json, text/plain, */*',
|
|
182
|
-
'Content-Type': 'application/json',
|
|
183
|
-
Authorization: this.accessToken,
|
|
184
|
-
},
|
|
206
|
+
headers: Object.assign({ Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, (withToken ? { Authorization: this.accessToken } : {})),
|
|
185
207
|
body: JSON.stringify(body),
|
|
186
208
|
});
|
|
187
209
|
const json = await response.json();
|
|
@@ -243,18 +265,54 @@ function Initialize(config) {
|
|
|
243
265
|
return new Client(config);
|
|
244
266
|
}
|
|
245
267
|
|
|
268
|
+
/**
|
|
269
|
+
* PKCE (RFC 7636) for apps that cannot keep a client secret: a native app makes
|
|
270
|
+
* a fresh verifier for every sign-in, sends only its S256 challenge to the
|
|
271
|
+
* authorize page, and proves it holds the verifier when it exchanges the code.
|
|
272
|
+
* See https://hivesigner.com/docs/pkce
|
|
273
|
+
*/
|
|
274
|
+
function subtleCrypto() {
|
|
275
|
+
const c = globalThis.crypto;
|
|
276
|
+
if (!c || !c.subtle || typeof c.getRandomValues !== 'function') {
|
|
277
|
+
throw new Error('hivesigner: Web Crypto is not available. Node.js 20+ or a modern browser is required for PKCE.');
|
|
278
|
+
}
|
|
279
|
+
return c;
|
|
280
|
+
}
|
|
281
|
+
function base64url(bytes) {
|
|
282
|
+
let binary = '';
|
|
283
|
+
bytes.forEach((b) => {
|
|
284
|
+
binary += String.fromCharCode(b);
|
|
285
|
+
});
|
|
286
|
+
const b64 = typeof btoa === 'function' ? btoa(binary) : Buffer.from(binary, 'binary').toString('base64');
|
|
287
|
+
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
288
|
+
}
|
|
289
|
+
/** BASE64URL(SHA256(verifier)), the S256 challenge of a verifier. */
|
|
290
|
+
async function pkceChallengeFor(codeVerifier) {
|
|
291
|
+
const digest = await subtleCrypto().subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
|
|
292
|
+
return base64url(new Uint8Array(digest));
|
|
293
|
+
}
|
|
294
|
+
/** A new verifier (32 random bytes, 43 characters) and its S256 challenge. */
|
|
295
|
+
async function createPkcePair() {
|
|
296
|
+
const codeVerifier = base64url(subtleCrypto().getRandomValues(new Uint8Array(32)));
|
|
297
|
+
return { codeVerifier, codeChallenge: await pkceChallengeFor(codeVerifier) };
|
|
298
|
+
}
|
|
299
|
+
|
|
246
300
|
var index = {
|
|
247
301
|
Client,
|
|
248
302
|
Initialize,
|
|
249
303
|
sendTransaction,
|
|
250
304
|
sendOperations,
|
|
251
305
|
sendOperation,
|
|
252
|
-
sign
|
|
306
|
+
sign,
|
|
307
|
+
createPkcePair,
|
|
308
|
+
pkceChallengeFor
|
|
253
309
|
};
|
|
254
310
|
|
|
255
311
|
exports.Client = Client;
|
|
256
312
|
exports.Initialize = Initialize;
|
|
313
|
+
exports.createPkcePair = createPkcePair;
|
|
257
314
|
exports["default"] = index;
|
|
315
|
+
exports.pkceChallengeFor = pkceChallengeFor;
|
|
258
316
|
exports.sendOperation = sendOperation;
|
|
259
317
|
exports.sendOperations = sendOperations;
|
|
260
318
|
exports.sendTransaction = sendTransaction;
|
package/lib/pkce.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PKCE (RFC 7636) for apps that cannot keep a client secret: a native app makes
|
|
3
|
+
* a fresh verifier for every sign-in, sends only its S256 challenge to the
|
|
4
|
+
* authorize page, and proves it holds the verifier when it exchanges the code.
|
|
5
|
+
* See https://hivesigner.com/docs/pkce
|
|
6
|
+
*/
|
|
7
|
+
export interface PkcePair {
|
|
8
|
+
/** Kept by the app until the exchange. Never put it in a URL. */
|
|
9
|
+
codeVerifier: string;
|
|
10
|
+
/** Sent as `code_challenge` with `code_challenge_method=S256`. */
|
|
11
|
+
codeChallenge: string;
|
|
12
|
+
}
|
|
13
|
+
/** BASE64URL(SHA256(verifier)), the S256 challenge of a verifier. */
|
|
14
|
+
export declare function pkceChallengeFor(codeVerifier: string): Promise<string>;
|
|
15
|
+
/** A new verifier (32 random bytes, 43 characters) and its S256 challenge. */
|
|
16
|
+
export declare function createPkcePair(): Promise<PkcePair>;
|
package/lib/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hivesigner",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Hivesigner SDK",
|
|
5
5
|
"main": "./lib/index",
|
|
6
6
|
"types": "./lib/index",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib"
|
|
9
|
+
],
|
|
7
10
|
"scripts": {
|
|
8
11
|
"build": "rimraf lib && webpack && rollup -c rollup.config.js && tsc --emitDeclarationOnly",
|
|
9
12
|
"test": "npx jest",
|
package/.eslintignore
DELETED
package/.eslintrc.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
|
|
3
|
-
extends: [
|
|
4
|
-
'plugin:@typescript-eslint/recommended' // Uses the recommended rules from @typescript-eslint/eslint-plugin
|
|
5
|
-
],
|
|
6
|
-
parserOptions: {
|
|
7
|
-
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
|
|
8
|
-
sourceType: 'module' // Allows for the use of imports
|
|
9
|
-
},
|
|
10
|
-
rules: {
|
|
11
|
-
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
|
|
12
|
-
// e.g. '@typescript-eslint/explicit-function-return-type': 'off',
|
|
13
|
-
"@typescript-eslint/ban-ts-comment": "off",
|
|
14
|
-
"@typescript-eslint/no-empty-function": "off"
|
|
15
|
-
}
|
|
16
|
-
};
|
package/CLAUDE.md
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
HiveSigner SDK is a JavaScript/TypeScript SDK for the Hive blockchain's OAuth2 authentication service (HiveSigner). It enables applications to authenticate users and perform Hive blockchain operations on their behalf. The SDK works in both browser and Node.js environments.
|
|
8
|
-
|
|
9
|
-
## Build & Development Commands
|
|
10
|
-
|
|
11
|
-
### Building
|
|
12
|
-
```bash
|
|
13
|
-
npm run build
|
|
14
|
-
```
|
|
15
|
-
This command:
|
|
16
|
-
1. Cleans the `lib/` directory
|
|
17
|
-
2. Runs webpack to create browser bundle (`lib/hivesigner.min.js`)
|
|
18
|
-
3. Runs rollup to create CommonJS module (`lib/index.js`)
|
|
19
|
-
4. Runs TypeScript compiler to emit type declarations (`lib/**/*.d.ts`)
|
|
20
|
-
|
|
21
|
-
### Testing
|
|
22
|
-
```bash
|
|
23
|
-
npm test
|
|
24
|
-
```
|
|
25
|
-
Runs all tests using Jest with ts-jest preset.
|
|
26
|
-
|
|
27
|
-
To run a single test file:
|
|
28
|
-
```bash
|
|
29
|
-
npx jest src/path/to/file.spec.ts
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Linting
|
|
33
|
-
```bash
|
|
34
|
-
npm run lint
|
|
35
|
-
```
|
|
36
|
-
Runs ESLint on all TypeScript files in `src/`.
|
|
37
|
-
|
|
38
|
-
## Architecture
|
|
39
|
-
|
|
40
|
-
### Core Components
|
|
41
|
-
|
|
42
|
-
**Client Class (`src/client.ts`)**
|
|
43
|
-
- Main entry point for SDK functionality
|
|
44
|
-
- Handles OAuth2 authentication flow (login, token management)
|
|
45
|
-
- Provides convenience methods for common Hive operations (vote, comment, follow, etc.)
|
|
46
|
-
- Uses method overloading to support both callback and Promise-based APIs
|
|
47
|
-
- All operations ultimately call `broadcast()` or `send()` methods
|
|
48
|
-
|
|
49
|
-
**Dual API Pattern**
|
|
50
|
-
The SDK supports both callbacks and Promises throughout. Each public method has overloaded signatures:
|
|
51
|
-
```typescript
|
|
52
|
-
public vote(...args): Promise<SendResponse>
|
|
53
|
-
public vote(...args, cb: CallbackFunction): Promise<SendResponse>
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Directory Structure
|
|
57
|
-
|
|
58
|
-
- `src/client.ts` - Main Client class with all SDK methods
|
|
59
|
-
- `src/methods/` - Standalone utility methods for operations like `sendOperation`, `sendOperations`, `sign`
|
|
60
|
-
- `src/factories/` - Factory functions (mainly deprecated `Initialize` function)
|
|
61
|
-
- `src/types/` - TypeScript interfaces and types
|
|
62
|
-
- `src/consts/` - Constants for API URLs (API_URL, BASE_URL, BETA_URL)
|
|
63
|
-
- `src/utilities/` - Helper utilities like `isBrowser()`
|
|
64
|
-
|
|
65
|
-
### Key Concepts
|
|
66
|
-
|
|
67
|
-
**Operation Broadcasting**
|
|
68
|
-
- Most methods construct an operation array and call `this.broadcast(operations, cb)`
|
|
69
|
-
- `broadcast()` sends operations to HiveSigner API's `/api/broadcast` endpoint
|
|
70
|
-
- Operations follow Hive blockchain operation format (from `@hiveio/dhive`)
|
|
71
|
-
|
|
72
|
-
**Authentication Flow**
|
|
73
|
-
1. App creates Client instance with `app`, `callbackURL`, and `scope`
|
|
74
|
-
2. User redirects to URL from `getLoginURL()` or calls `login()`
|
|
75
|
-
3. HiveSigner redirects back with `access_token` in query params
|
|
76
|
-
4. App sets token via `setAccessToken(accessToken)`
|
|
77
|
-
5. Authenticated calls include token in Authorization header
|
|
78
|
-
|
|
79
|
-
**URI Encoding for Operations**
|
|
80
|
-
- `sendOperation()` and `sendOperations()` use `hive-uri` package to encode operations as hive:// URIs
|
|
81
|
-
- These URIs are converted to HiveSigner web URLs for browser-based signing
|
|
82
|
-
|
|
83
|
-
## Build Output
|
|
84
|
-
|
|
85
|
-
The build produces three main artifacts in `lib/`:
|
|
86
|
-
- `index.js` + `index.d.ts` - CommonJS module with TypeScript declarations
|
|
87
|
-
- `hivesigner.min.js` - Webpack-bundled browser build (UMD format)
|
|
88
|
-
- Directory structure mirrors `src/` for individual module imports
|
|
89
|
-
|
|
90
|
-
## TypeScript Configuration
|
|
91
|
-
|
|
92
|
-
- Target: ES5 for broad compatibility
|
|
93
|
-
- Module: CommonJS
|
|
94
|
-
- Declaration files are generated for all modules
|
|
95
|
-
- Test files (`*.spec.ts`) are excluded from compilation
|
|
96
|
-
|
|
97
|
-
## Dependencies
|
|
98
|
-
|
|
99
|
-
**Runtime:**
|
|
100
|
-
- `cross-fetch` - Isomorphic fetch for Node.js and browser
|
|
101
|
-
- `hive-uri` - Encoding/decoding Hive operation URIs
|
|
102
|
-
- `@hiveio/dhive` (devDep, used for types) - Hive blockchain library
|
|
103
|
-
|
|
104
|
-
**Build:**
|
|
105
|
-
- Webpack for browser bundle
|
|
106
|
-
- Rollup for CommonJS build
|
|
107
|
-
- TypeScript for compilation and type checking
|
|
108
|
-
- Jest + ts-jest for testing
|
|
109
|
-
|
|
110
|
-
## Known Issues & Fixes
|
|
111
|
-
|
|
112
|
-
### "Illegal invocation" Error with Fetch
|
|
113
|
-
When using the SDK in browser environments, you may encounter:
|
|
114
|
-
```
|
|
115
|
-
TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**Cause**: The native browser `fetch` function loses its binding to the `window` object when imported and called through `cross-fetch`.
|
|
119
|
-
|
|
120
|
-
**Fix Applied**: The fetch function is now explicitly bound at module load time in `src/client.ts`:
|
|
121
|
-
```typescript
|
|
122
|
-
const fetch = crossFetch.bind(typeof globalThis !== 'undefined' ? globalThis : undefined)
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
This ensures the fetch function maintains proper context in both browser and Node.js environments.
|
|
126
|
-
|
|
127
|
-
### Webpack Build Error with Node.js 17+
|
|
128
|
-
When building with Node.js 17+, you may encounter:
|
|
129
|
-
```
|
|
130
|
-
Error: error:0308010C:digital envelope routines::unsupported
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**Cause**: Webpack 4 uses the MD4 hash algorithm which was removed in OpenSSL 3.0 (used by Node.js 17+).
|
|
134
|
-
|
|
135
|
-
**Fix Applied**: The build script now uses the legacy OpenSSL provider:
|
|
136
|
-
```bash
|
|
137
|
-
NODE_OPTIONS=--openssl-legacy-provider webpack
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Alternative Solutions**:
|
|
141
|
-
- Use Node.js 16 or earlier
|
|
142
|
-
- Upgrade to Webpack 5 (requires dependency updates)
|
package/docs/CNAME
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
demo.hivesigner.com
|