bsv-bap 0.1.10 → 0.1.11

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.
@@ -1,14 +1,17 @@
1
- import { PublicKey, type PrivateKey } from "@bsv/sdk";
2
- import type { HD } from "@bsv/sdk";
1
+ import { PublicKey, type PrivateKey, HD } from "@bsv/sdk";
3
2
  import { type APIFetcher } from "./api";
4
3
  import type { GetAttestationResponse, GetSigningKeysResponse } from "./apiTypes";
5
4
  import type { Identity, IdentityAttributes, OldIdentity, MemberIdentity } from "./interface";
6
5
  import { MemberID } from "./MemberID";
7
6
  import { BaseClass } from "./BaseClass";
7
+ interface Type42KeySource {
8
+ rootPk: PrivateKey;
9
+ }
8
10
  /**
9
11
  * MasterID class
10
12
  *
11
13
  * This class should be used in conjunction with the BAP class
14
+ * Supports both BIP32 (HD) and Type 42 key derivation
12
15
  *
13
16
  * @type {MasterID}
14
17
  */
@@ -20,7 +23,7 @@ declare class MasterID extends BaseClass {
20
23
  identityKey: string;
21
24
  identityAttributes: IdentityAttributes;
22
25
  getApiData: APIFetcher;
23
- constructor(HDPrivateKey: HD, identityAttributes?: IdentityAttributes, idSeed?: string);
26
+ constructor(keySource: HD | Type42KeySource, identityAttributes?: IdentityAttributes, idSeed?: string);
24
27
  set BAP_SERVER(bapServer: string);
25
28
  get BAP_SERVER(): string;
26
29
  set BAP_TOKEN(token: string);
@@ -121,6 +124,7 @@ declare class MasterID extends BaseClass {
121
124
  };
122
125
  /**
123
126
  * Get the encryption key using type 42 (different key / incompatible with above)
127
+ * @deprecated Use getEncryptionKey() which now handles both BIP32 and Type 42
124
128
  */
125
129
  getEncryptionKeyType42(): {
126
130
  privKey: PrivateKey;
package/dist/index.cjs ADDED
@@ -0,0 +1,8 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var{defineProperty:g,getOwnPropertyNames:s,getOwnPropertyDescriptor:i}=Object,r=Object.prototype.hasOwnProperty;var K=new WeakMap,a=(j)=>{var $=K.get(j),J;if($)return $;if($=g({},"__esModule",{value:!0}),j&&typeof j==="object"||typeof j==="function")s(j).map((q)=>!r.call($,q)&&g($,q,{get:()=>j[q],enumerable:!(J=i(j,q))||J.enumerable}));return K.set(j,$),$};var e=(j,$)=>{for(var J in $)g(j,J,{get:$[J],enumerable:!0,configurable:!0,set:(q)=>$[J]=()=>q})};var Zj={};e(Zj,{MemberID:()=>_,MasterID:()=>V,BAP:()=>y});module.exports=a(Zj);var Y=require("@bsv/sdk"),d=require("@bsv/sdk");var t=async(j,$,J,q)=>{let z=`${J}${j}`;return(await fetch(z,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},S=(j,$)=>async(J,q)=>{return t(J,q,j,$)};var c=require("@bsv/sdk"),{toHex:b,toArray:m}=c.Utils,k="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",p=b(m(k)),B="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",Gj=b(m(B)),D="https://api.sigmaidentity.com/v1",M=2147483647,x="m/424150'/0'/0'",X=`m/424150'/${M}'/${M}'`;var Z=require("@bsv/sdk");var C={getRandomBytes(j=32){if(typeof globalThis!=="undefined"&&globalThis.crypto&&globalThis.crypto.getRandomValues){let $=new Uint8Array(j);return globalThis.crypto.getRandomValues($),$}throw new Error("Secure random number generation not available. crypto.getRandomValues() is required for cryptographic operations. This environment may not be suitable for secure key generation.")},getRandomString(j=32){let $=this.getRandomBytes(j);return Array.from($,(J)=>J.toString(16).padStart(2,"0")).join("")},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let z=2147483647;for(let Q of q){let L=Number(`0x${Q}`);if(L>z)L-=z;J+=`/${L}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let z=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=z+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let z=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=z+(q?"'":""),$.join("/")}};var F=require("@bsv/sdk");var U=require("@bsv/sdk");var{toArray:O,toUTF8:jj,toBase64:$j}=U.Utils,{electrumDecrypt:Jj,electrumEncrypt:qj}=U.ECIES;class N{identityAttributes={};encrypt(j,$){let{privKey:J,pubKey:q}=this.getEncryptionKey(),z=$?U.PublicKey.fromString($):q;return $j(qj(O(j),z,J))}decrypt(j,$){let{privKey:J}=this.getEncryptionKey(),q=void 0;if($)q=U.PublicKey.fromString($);return jj(Jj(O(j,"base64"),J,q))}signOpReturnWithAIP(j,$){let J=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage(J.flat(),$);return this.formatAIPOutput(J,q,z)}getAttributes(){return this.identityAttributes}getAttribute(j){if(this.identityAttributes[j])return this.identityAttributes[j];return null}setAttribute(j,$){if(!$)return;if(this.identityAttributes[j])this.updateExistingAttribute(j,$);else this.createNewAttribute(j,$)}unsetAttribute(j){delete this.identityAttributes[j]}addAttribute(j,$,J=""){let q=J;if(!J)q=C.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}getAttributeUrns(){let j="";for(let $ in this.identityAttributes){let J=this.getAttributeUrn($);if(J)j+=`${J}
3
+ `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}parseStringUrns(j){let $={},J=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
4
+ `);for(let q of J){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let $ in j)if(!j[$].value||!j[$].nonce)throw new Error("Invalid identity attribute");return j||{}}updateExistingAttribute(j,$){if(typeof $==="string"){this.identityAttributes[j].value=$;return}if(this.identityAttributes[j].value=$.value||"",$.nonce)this.identityAttributes[j].nonce=$.nonce}createNewAttribute(j,$){if(typeof $==="string"){this.addAttribute(j,$);return}this.addAttribute(j,$.value||"",$.nonce)}getAIPMessageBuffer(j,$){let J=j.findIndex((z)=>z[0]===U.OP.OP_RETURN),q=[];if(J===-1)q.push([U.OP.OP_RETURN]),J=0;if($)for(let z of $)q.push(j[J+z]);else for(let z of j)q.push(z);return q}formatAIPOutput(j,$,J){let q=[O("|"),O(B),O("BITCOIN_ECDSA"),O($),O(J,"base64")];return[...j,...q]}}var{magicHash:zj}=F.BSM;class _ extends N{key;idName;description;address;identityKey;constructor(j,$={}){super();this.key=j,this.address=j.toAddress(),this.idName="Member ID 1",this.description="",this.identityKey="",this.identityAttributes=this.parseAttributes($)}signMessage(j,$){let J=this.key,q=J.toAddress(),z=F.BSM.sign(j,J,"raw"),Q=new F.BigNumber(zj(j)),L=z.CalculateRecoveryFactor(J.toPublicKey(),Q),w=F.BSM.sign(j,J,"raw").toCompact(L,!0,"base64");return{address:q,signature:w}}signOpReturnWithAIP(j){let $=this.getAIPMessageBuffer(j),{address:J,signature:q}=this.signMessage($.flat());return this.formatAIPOutput($,J,q)}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=F.PrivateKey.fromWif(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes||{},this.identityKey=j.identityKey}static fromMemberIdentity(j){let $=new _(F.PrivateKey.fromWif(j.derivedPrivateKey));return $.import(j),$}static fromBackup(j){let $=new _(F.PrivateKey.fromWif(j.wif)),J=JSON.parse($.decrypt(j.id));return $.import(J),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toWif(),address:this.address,identityAttributes:this.getAttributes(),identityKey:this.identityKey}}getEncryptionKey(){return{privKey:this.key.deriveChild(this.key.toPublicKey(),X),pubKey:this.key.deriveChild(this.key.toPublicKey(),X).toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}exportForBackup(j){let $=this.export(),J=this.encrypt(JSON.stringify($));return{wif:this.key.toWif(),id:J,...j&&{label:j},createdAt:new Date().toISOString()}}}var{toArray:f,toHex:R,toBase58:Qj,toUTF8:h,toBase64:v}=Z.Utils,{electrumDecrypt:P,electrumEncrypt:A}=Z.ECIES,{magicHash:o}=Z.BSM;class V extends N{#$;#j;#J;#Q=D;#W="";#q;#Z;#z;#L;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){super();if(j instanceof Z.HD)if(this.#J=!1,J){let z=R(Z.Hash.sha256(J,"utf8")),Q=C.getSigningPathFromHex(z);this.#$=j.derive(Q)}else this.#$=j;else if(this.#J=!0,this.#j=j.rootPk,J){let z=R(Z.Hash.sha256(J,"utf8"));this.#j=this.#j.deriveChild(this.#j.toPublicKey(),z)}if(this.#L=J,this.idName="ID 1",this.description="",this.#q=`${x}/0/0/0`,this.#Z=`${x}/0/0/0`,this.#z=`${x}/0/0/1`,this.#J){if(!this.#j)throw new Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#q);this.rootAddress=z.toPublicKey().toAddress()}else{if(!this.#$)throw new Error("HD private key not initialized");let z=this.#$.derive(this.#q);this.rootAddress=z.privKey.toPublicKey().toAddress()}this.identityKey=this.deriveIdentityKey(this.rootAddress);let q={...$};this.identityAttributes=this.parseAttributes(q),this.getApiData=S(this.#Q,this.#W)}set BAP_SERVER(j){this.#Q=j}get BAP_SERVER(){return this.#Q}set BAP_TOKEN(j){this.#W=j}get BAP_TOKEN(){return this.#W}deriveIdentityKey(j){let $=R(Z.Hash.sha256(j,"utf8"));return Qj(Z.Hash.ripemd160($,"hex"))}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let $ in j)if(!j[$].value||!j[$].nonce)throw new Error("Invalid identity attribute");return j||{}}parseStringUrns(j){let $={},J=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
5
+ `);for(let q of J){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}getIdentityKey(){return this.identityKey}set rootPath(j){if(this.#J){if(this.#q=j,!this.#j)throw new Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),j);this.rootAddress=$.toPublicKey().toAddress(),this.#Z=j,this.#z=j}else{let $=j;if(j.split("/").length<5)$=`${x}${j}`;if(!this.validatePath($))throw new Error(`invalid signing path given ${$}`);if(this.#q=$,!this.#$)throw new Error("HD private key not initialized");let J=this.#$.derive($);this.rootAddress=J.pubKey.toAddress(),this.#Z=$,this.#z=$}this.identityKey=this.deriveIdentityKey(this.rootAddress)}get rootPath(){return this.#q}getRootPath(){return this.#q}set currentPath(j){if(this.#J)this.#Z=this.#z,this.#z=j;else{let $=j;if(j.split("/").length<5)$=`${x}${j}`;if(!this.validatePath($))throw new Error("invalid signing path given");this.#Z=this.#z,this.#z=$}}get currentPath(){return this.#z}get previousPath(){return this.#Z}get idSeed(){return this.#L}incrementPath(){this.currentPath=C.getNextPath(this.currentPath)}validatePath(j){if(j.match(/\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?/)){let $=j.split("/");if($.length===7&&Number($[1].replace("'",""))<=M&&Number($[2].replace("'",""))<=M&&Number($[3].replace("'",""))<=M&&Number($[4].replace("'",""))<=M&&Number($[5].replace("'",""))<=M&&Number($[6].replace("'",""))<=M)return!0}return!1}getInitialIdTransaction(){return this.getIdTransaction(this.#q)}getIdTransaction(j=""){if(this.#z===this.#q)throw new Error("Current path equals rootPath. ID was probably not initialized properly");let $=[f(k),f("ID"),f(this.identityKey),f(this.getCurrentAddress())];return this.signOpReturnWithAIP($,j||this.#Z)}getAddress(j){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");return this.#j.deriveChild(this.#j.toPublicKey(),j).toPublicKey().toAddress()}if(!this.#$)throw new Error("HD private key not initialized");return this.#$.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionKey(){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),this.#q),q=J.deriveChild(J.toPublicKey(),X);return{privKey:q,pubKey:q.toPublicKey()}}if(!this.#$)throw new Error("HD private key not initialized");let $=this.#$.derive(this.#q).derive(X).privKey;return{privKey:$,pubKey:$.toPublicKey()}}getEncryptionKeyType42(){if(this.#J)return this.getEncryptionKey();if(!this.#$)throw new Error("HD private key not initialized");let j=this.#$.derive(this.#q),$=j.privKey.deriveChild(j.toPublic().pubKey,X);return{privKey:$,pubKey:$.toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encrypt(j,$){let{privKey:J,pubKey:q}=this.getEncryptionKey(),z=$?Z.PublicKey.fromString($):q;return v(A(f(j),z,null))}decrypt(j,$){let{privKey:J}=this.getEncryptionKey(),q=void 0;if($)q=Z.PublicKey.fromString($);return h(P(f(j,"base64"),J,q))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),z=q.toPublicKey(),Q=J?Z.PublicKey.fromString(J):z;return v(A(f(j),Q,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),z=void 0;if(J)z=Z.PublicKey.fromString(J);return h(P(f(j,"base64"),q,z))}getEncryptionPrivateKeyWithSeed(j){let $=R(Z.Hash.sha256(j,"utf8"));if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#q);return z.deriveChild(z.toPublicKey(),$)}if(!this.#$)throw new Error("HD private key not initialized");let J=C.getSigningPathFromHex($);return this.#$.derive(this.#q).derive(J).privKey}getAttestation(j){let $=Z.Hash.sha256(j,"utf8");return`bap:attest:${R($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=Z.Hash.sha256(J,"utf8");return R(q)}signMessage(j,$){let J=$||this.#z,q;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");q=this.#j.deriveChild(this.#j.toPublicKey(),J)}else{if(!this.#$)throw new Error("HD private key not initialized");q=this.#$.derive(J).privKey}let z=q.toAddress(),Q=Z.BSM.sign(j,q,"raw"),L=new Z.BigNumber(o(j)),w=Q.CalculateRecoveryFactor(q.toPublicKey(),L),G=Z.BSM.sign(j,q,"raw").toCompact(w,!0,"base64");return{address:z,signature:G}}signMessageWithSeed(j,$){let J=R(Z.Hash.sha256($,"utf8")),q;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let H=this.#j.deriveChild(this.#j.toPublicKey(),this.#q);q=H.deriveChild(H.toPublicKey(),J)}else{if(!this.#$)throw new Error("HD private key not initialized");let H=C.getSigningPathFromHex(J);q=this.#$.derive(this.#q).derive(H).privKey}let z=q.toPublicKey().toAddress(),Q=f(j,"utf8"),L=Z.BSM.sign(Q,q,"raw"),w=new Z.BigNumber(o(Q)),G=L.CalculateRecoveryFactor(q.toPublicKey(),w),T=Z.BSM.sign(Q,q,"raw").toCompact(G,!0,"base64");return{address:z,signature:T}}signOpReturnWithAIP(j,$=""){let J=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage(J.flat(),$);return this.formatAIPOutput(j,q,z)}async getIdSigningKeys(){let j=await this.getApiData("/signing-keys",{idKey:this.identityKey});return console.log("getIdSigningKeys",j),j}async getAttributeAttestations(j){let $=this.getAttestationHash(j),J=await this.getApiData("/attestation/get",{hash:$});return console.log("getAttestations",j,$,J),J}import(j){this.idName=j.name,this.description=j.description||"",this.identityKey=j.identityKey,this.#q=j.rootPath,this.rootAddress=j.rootAddress,this.#Z=j.previousPath,this.#z=j.currentPath,this.#L=("idSeed"in j?j.idSeed:"")||"",this.identityAttributes=this.parseAttributes(j.identityAttributes)}export(){return{name:this.idName,description:this.description,identityKey:this.identityKey,rootPath:this.#q,rootAddress:this.rootAddress,previousPath:this.#Z,currentPath:this.#z,idSeed:this.#L,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");j=this.#j.deriveChild(this.#j.toPublicKey(),this.#z)}else{if(!this.#$)throw new Error("HD private key not initialized");j=this.#$.derive(this.#z).privKey}return{name:this.idName,description:this.description,derivedPrivateKey:j.toWif(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes(),identityKey:this.identityKey}}newId(){this.incrementPath();let j;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");j=this.#j.deriveChild(this.#j.toPublicKey(),this.#z)}else{if(!this.#$)throw new Error("HD private key not initialized");j=this.#$.derive(this.#z).privKey}return new _(j)}exportMember(){let j=this.exportMemberBackup(),$;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");$=this.#j.deriveChild(this.#j.toPublicKey(),this.#z)}else{if(!this.#$)throw new Error("HD private key not initialized");$=this.#$.derive(this.#z).privKey}let J=v(A(f(JSON.stringify(j)),$.toPublicKey()));return{wif:j.derivedPrivateKey,encryptedData:J}}}var{toArray:W,toUTF8:E,toBase64:l,toHex:I}=d.Utils,{electrumEncrypt:n,electrumDecrypt:u}=Y.ECIES;class y{#$;#j;#J;#Q={};#W=D;#q="";#Z="";#z=0;getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No key source given");if(typeof j==="string")this.#$=Y.HD.fromString(j),this.#J=!1;else this.#j=Y.PrivateKey.fromWif(j.rootPk),this.#J=!0;if($)this.#q=$;if(J)this.#W=J;this.getApiData=S(this.#W,this.#q)}get lastIdPath(){return this.#Z}getPublicKey(j=""){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");if(j)return this.#j.deriveChild(this.#j.toPublicKey(),j).toPublicKey().toString();return this.#j.toPublicKey().toString()}if(!this.#$)throw new Error("HD private key not initialized");if(j)return this.#$.derive(j).pubKey.toString();return this.#$.pubKey.toString()}getHdPublicKey(j=""){if(this.#J)throw new Error("HD public keys are not available in Type 42 mode");if(!this.#$)throw new Error("HD private key not initialized");if(j)return this.#$.derive(j).toPublic().toString();return this.#$.toPublic().toString()}set BAP_SERVER(j){this.#W=j;for(let $ in this.#Q)this.#Q[$].BAP_SERVER=j}get BAP_SERVER(){return this.#W}set BAP_TOKEN(j){this.#q=j;for(let $ in this.#Q)this.#Q[$].BAP_TOKEN=j}get BAP_TOKEN(){return this.#q}checkIdBelongs(j){let $;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");$=this.#j.deriveChild(this.#j.toPublicKey(),j.rootPath).toPublicKey().toAddress()}else{if(!this.#$)throw new Error("HD private key not initialized");$=this.#$.derive(j.rootPath).pubKey.toAddress()}if($!==j.rootAddress)throw new Error("ID does not belong to this private key");return!0}listIds(){return Object.keys(this.#Q)}newId(j,$,J={},q=""){let z,Q,L;if(typeof j==="object"||j===void 0||typeof j==="string"&&j.startsWith("/"))Q=typeof j==="string"?j:void 0,L=typeof j==="object"?j:typeof $==="object"?$:{},z="Default Identity";else z=j,Q=typeof $==="string"?$:void 0,L=typeof $==="object"?$:J;let w;if(Q)w=Q;else if(this.#J)w=`bap:${this.#z}`,this.#z++;else w=this.getNextValidPath();let G;if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");G=new V({rootPk:this.#j},L,q)}else{if(!this.#$)throw new Error("HD private key not initialized");G=new V(this.#$,L,q)}if(G.BAP_SERVER=this.#W,G.BAP_TOKEN=this.#q,G.idName=z,G.rootPath=w,this.#J)G.currentPath=w;else G.currentPath=C.getNextPath(w);let T=G.getIdentityKey();return this.#Q[T]=G,this.#Z=w,this.#Q[T]}removeId(j){delete this.#Q[j]}getNextValidPath(){if(this.#Z)return C.getNextIdentityPath(this.#Z);return`/0'/${Object.keys(this.#Q).length}'/0'`}newIdWithCounter(j,$=`Identity ${j}`){if(!this.#J)throw new Error("newIdWithCounter only works in Type 42 mode");let J=`bap:${j}`;return this.newId($,J)}getId(j){return this.#Q[j]||null}setId(j){this.checkIdBelongs(j),this.#Q[j.getIdentityKey()]=j}importIds(j,$=!0){if($&&typeof j==="string"){this.importEncryptedIds(j);return}let J=j;if(!J.lastIdPath)throw new Error("ID cannot be imported as it is not complete");if(!J.ids)throw new Error(`ID data is not in the correct format: ${j}`);let q=j.lastIdPath;for(let z of J.ids){if(!z.identityKey||!z.identityAttributes||!z.rootAddress)throw new Error("ID cannot be imported as it is not complete");let Q;if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");Q=new V({rootPk:this.#j},{},z.idSeed)}else{if(!this.#$)throw new Error("HD private key not initialized");Q=new V(this.#$,{},z.idSeed)}if(Q.BAP_SERVER=this.#W,Q.BAP_TOKEN=this.#q,Q.import(z),q==="")q=Q.currentPath;if(this.checkIdBelongs(Q),this.#Q[Q.getIdentityKey()]=Q,this.#J&&Q.rootPath.startsWith("bap:")){let L=Q.rootPath.split(":");if(L.length>=2){let w=parseInt(L[1],10);if(!isNaN(w))this.#z=Math.max(this.#z,w+1)}}}this.#Z=q}importEncryptedIds(j){let $=this.decrypt(j),J=JSON.parse($);if(Array.isArray(J)){console.log(`Importing old format:
6
+ `,J),this.importOldIds(J);return}if(typeof J!=="object")throw new Error("decrypted, but found unrecognized identities format");this.importIds(J,!1)}importOldIds(j){for(let $ of j){let J;if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");J=new V({rootPk:this.#j},{},$.idSeed??"")}else{if(!this.#$)throw new Error("HD private key not initialized");J=new V(this.#$,{},$.idSeed??"")}J.BAP_SERVER=this.#W,J.BAP_TOKEN=this.#q,J.import($),this.checkIdBelongs(J),this.#Q[J.getIdentityKey()]=J,this.#Z=J.currentPath}}exportIds(j,$=!0){let J={lastIdPath:this.#Z,ids:[]},q=j||Object.keys(this.#Q);for(let z of q){if(!this.#Q[z])throw new Error(`Identity ${z} not found`);J.ids.push(this.#Q[z].export())}if($)return this.encrypt(JSON.stringify(J));return J}exportId(j,$=!0){let J={lastIdPath:this.#Z,ids:[]};if(J.ids.push(this.#Q[j].export()),$)return this.encrypt(JSON.stringify(J));return J}encrypt(j){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),X);return l(n(W(j),J.toPublicKey(),null))}if(!this.#$)throw new Error("HD private key not initialized");let $=this.#$.derive(X);return l(n(W(j),$.pubKey,null))}decrypt(j){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),X);return E(u(W(j,"base64"),J))}if(!this.#$)throw new Error("HD private key not initialized");let $=this.#$.derive(X);return E(u(W(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let z=this.getId($);if(!z)throw new Error("Could not find identity to attest with");let Q=this.getAttestationBuffer(j,J,q),{address:L,signature:w}=z.signMessage(Q);return this.createAttestationTransaction(j,J,L,w,q)}verifyAttestationWithAIP(j){if(!j.every((q)=>Array.isArray(q))||j[0][0]!==Y.OP.OP_RETURN||I(j[1])!==p)throw new Error("Not a valid BAP transaction");let $=I(j[7])==="44415441"?5:0,J={type:E(j[2]),hash:I(j[3]),sequence:E(j[4]),signingProtocol:E(j[7+$]),signingAddress:E(j[8+$]),signature:l(j[9+$])};if($&&j[3]===j[8])J.data=I(j[9]);console.log({attestation:J});try{let q=[];for(let z=0;z<6+$;z++)q.push(j[z]);J.verified=this.verifySignature(q.flat(),J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,z=""){let Q=[[Y.OP.OP_RETURN],W(k),W("ATTEST"),W(j),W(`${$}`),W("|")];if(z)Q.push(W(k),W("DATA"),W(j),W(z),W("|"));return Q.push(W(B),W("BITCOIN_ECDSA"),W(J),W(q,"base64")),console.log({elements:Q}),Q}getAttestationBuffer(j,$=0,J=""){let q=[[Y.OP.OP_RETURN],W(k),W("ATTEST"),W(j),W(`${$}`),W("|")];if(J)q.push(W(k),W("DATA"),W(j),W(J),W("|"));return q.flat()}verifySignature(j,$,J){let q;if(Array.isArray(j))q=j;else if(Buffer.isBuffer(j))q=[...j];else q=W(j,"utf8");let z=Y.Signature.fromCompact(J,"base64"),Q;for(let L=0;L<4;L++)try{if(Q=z.RecoverPublicKey(L,new Y.BigNumber(Y.BSM.magicHash(q))),Y.BSM.verify(q,z,Q)&&Q.toAddress()===$)return!0}catch(w){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let Q=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(Q?.status==="success"&&Q?.result?.valid===!0)return!0;return!1}catch(Q){return console.error("API call failed:",Q),!1}}async isValidAttestationTransaction(j){if(this.verifyAttestationWithAIP(j))return this.getApiData("/attestation/valid",{tx:j});return!1}async getIdentityFromAddress(j){return this.getApiData("/identity/from-address",{address:j})}async getIdentity(j){return this.getApiData("/identity/get",{idKey:j})}async getAttestationsForHash(j){return this.getApiData("/attestations",{hash:j})}exportForBackup(j,$,J){let z={ids:this.exportIds(),...j&&{label:j},createdAt:new Date().toISOString()};if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");return{...z,rootPk:this.#j.toWif()}}if(!this.#$)throw new Error("HD private key not initialized");return{...z,xprv:$||this.#$.toString(),mnemonic:J||""}}exportMemberForBackup(j,$){let J=this.#Q[j];if(!J)throw new Error(`Identity ${j} not found`);let q=J.exportMember();return{wif:q.wif,id:q.encryptedData,...$&&{label:$},createdAt:new Date().toISOString()}}}})
7
+
8
+ //# debugId=FA9CA22E0EA4085964756E2164756E21
package/dist/index.d.ts CHANGED
@@ -7,27 +7,34 @@ type Identities = {
7
7
  lastIdPath: string;
8
8
  ids: Identity[];
9
9
  };
10
+ interface Type42Params {
11
+ rootPk: string;
12
+ }
10
13
  /**
11
14
  * BAP class
12
15
  *
13
16
  * Creates an instance of the BAP class and uses the given HDPrivateKey for all BAP operations.
17
+ * Supports both BIP32 (HD) and Type 42 key derivation methods.
18
+ *
19
+ * @deprecated When initializing with a string (xprv), the BIP32 format is used which is deprecated
20
+ * for new implementations. Use Type 42 initialization with { rootPk: wifKey } instead.
14
21
  *
15
- * @param HDPrivateKey
22
+ * @param keySource Either an HDPrivateKey string (xprv) for BIP32 or Type42Params for Type 42
16
23
  */
17
24
  export declare class BAP {
18
25
  #private;
19
26
  getApiData: APIFetcher;
20
- constructor(HDPrivateKey: string, token?: string, server?: string);
27
+ constructor(keySource: string | Type42Params, token?: string, server?: string);
21
28
  get lastIdPath(): string;
22
29
  /**
23
30
  * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty
24
31
  *
25
- * @param childPath Full derivation path for this child
32
+ * @param childPath Full derivation path for this child (BIP32) or invoice number (Type 42)
26
33
  * @returns {*}
27
34
  */
28
35
  getPublicKey(childPath?: string): string;
29
36
  /**
30
- * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty
37
+ * Get the HD public key of the given childPath (BIP32 only)
31
38
  *
32
39
  * @param childPath Full derivation path for this child
33
40
  * @returns {*}
@@ -53,16 +60,19 @@ export declare class BAP {
53
60
  /**
54
61
  * Create a new Id and link it to this BAP instance
55
62
  *
56
- * This function uses the length of the #ids of this class to determine the next valid path.
57
- * If not all ids related to this HDPrivateKey have been loaded, determine the path externally
58
- * and pass it to newId when creating a new ID.
63
+ * For Type 42 mode, uses simple counter for derivation: bap:{counter}
64
+ * For BIP32 mode (legacy), uses traditional HD paths or provided customPath
59
65
  *
60
- * @param path
61
- * @param identityAttributes
62
- * @param idSeed
63
- * @returns {*}
66
+ * New signature: newId(idName, customPath?, identityAttributes?, idSeed?)
67
+ * Legacy signature: newId(path?, identityAttributes?, idSeed?) - for backward compatibility
68
+ *
69
+ * @param idNameOrPath The human-readable name for this identity OR legacy path parameter
70
+ * @param customPathOrAttributes Optional custom derivation path OR legacy identityAttributes
71
+ * @param identityAttributes Optional identity attributes
72
+ * @param idSeed Optional seed for deterministic key generation
73
+ * @returns {MasterID} The created identity
64
74
  */
65
- newId(path?: string, identityAttributes?: IdentityAttributes, idSeed?: string): MasterID;
75
+ newId(idNameOrPath?: string | IdentityAttributes, customPathOrAttributes?: string | IdentityAttributes, identityAttributes?: IdentityAttributes, idSeed?: string): MasterID;
66
76
  /**
67
77
  * Remove identity
68
78
  *
@@ -76,6 +86,15 @@ export declare class BAP {
76
86
  * @returns {string}
77
87
  */
78
88
  getNextValidPath(): PathPrefix;
89
+ /**
90
+ * Create an identity with a specific counter value (useful for discovery)
91
+ * Only works in Type 42 mode
92
+ *
93
+ * @param counter The specific counter value to use
94
+ * @param idName Optional name for the identity
95
+ * @returns {MasterID} The created identity
96
+ */
97
+ newIdWithCounter(counter: number, idName?: string): MasterID;
79
98
  /**
80
99
  * Get a certain Id
81
100
  *
@@ -240,15 +259,21 @@ export declare class BAP {
240
259
  getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse>;
241
260
  /**
242
261
  * Export master BAP data in bitcoin-backup compatible format
262
+ * Automatically handles both BIP32 and Type 42 modes
263
+ *
264
+ * @deprecated BIP32 format export (when initialized with xprv) is deprecated.
265
+ * Use Type 42 initialization with { rootPk: wifKey } for new implementations.
266
+ *
243
267
  * @param label Optional user-defined label
244
- * @param xprv Extended private key (if not provided, the HDPrivateKey will be used)
245
- * @param mnemonic BIP39 mnemonic phrase (optional)
246
- * @returns BapMasterBackup compatible object
268
+ * @param xprv Extended private key (BIP32 mode only - if not provided, the HDPrivateKey will be used)
269
+ * @param mnemonic BIP39 mnemonic phrase (BIP32 mode only - optional)
270
+ * @returns BapMasterBackup compatible object (format depends on key type)
247
271
  */
248
272
  exportForBackup(label?: string, xprv?: string, mnemonic?: string): {
249
273
  ids: string;
250
- xprv: string;
251
- mnemonic: string;
274
+ xprv?: string;
275
+ mnemonic?: string;
276
+ rootPk?: string;
252
277
  label?: string;
253
278
  createdAt: string;
254
279
  };
@@ -266,4 +291,4 @@ export declare class BAP {
266
291
  };
267
292
  }
268
293
  export { MasterID, MemberID };
269
- export type { Attestation, Identity, MemberIdentity, IdentityAttributes, PathPrefix, };
294
+ export type { Attestation, Identity, MemberIdentity, IdentityAttributes, PathPrefix, Type42Params, };
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{BSM as g,BigNumber as Wj,ECIES as wj,HD as Lj,OP as K,Signature as Yj}from"@bsv/sdk";import{Utils as Gj}from"@bsv/sdk";var s=async(j,$,J,q)=>{let z=`${J}${j}`;return(await fetch(z,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},x=(j,$)=>async(J,q)=>{return s(J,q,j,$)};import{Utils as r}from"@bsv/sdk";var{toHex:A,toArray:m}=r,X="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",c=A(m(X)),M="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",Oj=A(m(M)),N="https://api.sigmaidentity.com/v1",F=2147483647,f="m/424150'/0'/0'",L=`m/424150'/${F}'/${F}'`;import{BSM as _,Utils as zj,ECIES as Qj,Hash as U,PublicKey as E,BigNumber as h}from"@bsv/sdk";var Y={getRandomBytes(j=32){if(typeof globalThis!=="undefined"&&globalThis.crypto&&globalThis.crypto.getRandomValues){let $=new Uint8Array(j);return globalThis.crypto.getRandomValues($),$}throw new Error("Secure random number generation not available. crypto.getRandomValues() is required for cryptographic operations. This environment may not be suitable for secure key generation.")},getRandomString(j=32){let $=this.getRandomBytes(j);return Array.from($,(J)=>J.toString(16).padStart(2,"0")).join("")},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let z=2147483647;for(let Q of q){let W=Number(`0x${Q}`);if(W>z)W-=z;J+=`/${W}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let z=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=z+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let z=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=z+(q?"'":""),$.join("/")}};import{BSM as H,Utils as Nj,PrivateKey as S,BigNumber as Jj}from"@bsv/sdk";import{ECIES as i,Utils as a,OP as l,PublicKey as p}from"@bsv/sdk";var{toArray:C,toUTF8:e,toBase64:t}=a,{electrumDecrypt:jj,electrumEncrypt:$j}=i;class V{identityAttributes={};encrypt(j,$){let{privKey:J,pubKey:q}=this.getEncryptionKey(),z=$?p.fromString($):q;return t($j(C(j),z,J))}decrypt(j,$){let{privKey:J}=this.getEncryptionKey(),q=void 0;if($)q=p.fromString($);return e(jj(C(j,"base64"),J,q))}signOpReturnWithAIP(j,$){let J=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage(J.flat(),$);return this.formatAIPOutput(J,q,z)}getAttributes(){return this.identityAttributes}getAttribute(j){if(this.identityAttributes[j])return this.identityAttributes[j];return null}setAttribute(j,$){if(!$)return;if(this.identityAttributes[j])this.updateExistingAttribute(j,$);else this.createNewAttribute(j,$)}unsetAttribute(j){delete this.identityAttributes[j]}addAttribute(j,$,J=""){let q=J;if(!J)q=Y.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}getAttributeUrns(){let j="";for(let $ in this.identityAttributes){let J=this.getAttributeUrn($);if(J)j+=`${J}
2
+ import{BSM as l,BigNumber as wj,ECIES as Yj,HD as Gj,OP as K,Signature as Xj,PrivateKey as Fj}from"@bsv/sdk";import{Utils as Cj}from"@bsv/sdk";var i=async(j,$,J,q)=>{let z=`${J}${j}`;return(await fetch(z,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},T=(j,$)=>async(J,q)=>{return i(J,q,j,$)};import{Utils as r}from"@bsv/sdk";var{toHex:b,toArray:m}=r,C="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",p=b(m(C)),R="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",Oj=b(m(R)),H="https://api.sigmaidentity.com/v1",F=2147483647,k="m/424150'/0'/0'",Y=`m/424150'/${F}'/${F}'`;import{BSM as E,Utils as Qj,ECIES as Zj,Hash as U,PublicKey as S,BigNumber as o,HD as Wj}from"@bsv/sdk";var G={getRandomBytes(j=32){if(typeof globalThis!=="undefined"&&globalThis.crypto&&globalThis.crypto.getRandomValues){let $=new Uint8Array(j);return globalThis.crypto.getRandomValues($),$}throw new Error("Secure random number generation not available. crypto.getRandomValues() is required for cryptographic operations. This environment may not be suitable for secure key generation.")},getRandomString(j=32){let $=this.getRandomBytes(j);return Array.from($,(J)=>J.toString(16).padStart(2,"0")).join("")},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let z=2147483647;for(let Q of q){let W=Number(`0x${Q}`);if(W>z)W-=z;J+=`/${W}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let z=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=z+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let z=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=z+(q?"'":""),$.join("/")}};import{BSM as g,Utils as Hj,PrivateKey as I,BigNumber as qj}from"@bsv/sdk";import{ECIES as a,Utils as e,OP as h,PublicKey as P}from"@bsv/sdk";var{toArray:M,toUTF8:t,toBase64:jj}=e,{electrumDecrypt:$j,electrumEncrypt:Jj}=a;class x{identityAttributes={};encrypt(j,$){let{privKey:J,pubKey:q}=this.getEncryptionKey(),z=$?P.fromString($):q;return jj(Jj(M(j),z,J))}decrypt(j,$){let{privKey:J}=this.getEncryptionKey(),q=void 0;if($)q=P.fromString($);return t($j(M(j,"base64"),J,q))}signOpReturnWithAIP(j,$){let J=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage(J.flat(),$);return this.formatAIPOutput(J,q,z)}getAttributes(){return this.identityAttributes}getAttribute(j){if(this.identityAttributes[j])return this.identityAttributes[j];return null}setAttribute(j,$){if(!$)return;if(this.identityAttributes[j])this.updateExistingAttribute(j,$);else this.createNewAttribute(j,$)}unsetAttribute(j){delete this.identityAttributes[j]}addAttribute(j,$,J=""){let q=J;if(!J)q=G.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}getAttributeUrns(){let j="";for(let $ in this.identityAttributes){let J=this.getAttributeUrn($);if(J)j+=`${J}
3
3
  `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}parseStringUrns(j){let $={},J=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
4
- `);for(let q of J){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let $ in j)if(!j[$].value||!j[$].nonce)throw new Error("Invalid identity attribute");return j||{}}updateExistingAttribute(j,$){if(typeof $==="string"){this.identityAttributes[j].value=$;return}if(this.identityAttributes[j].value=$.value||"",$.nonce)this.identityAttributes[j].nonce=$.nonce}createNewAttribute(j,$){if(typeof $==="string"){this.addAttribute(j,$);return}this.addAttribute(j,$.value||"",$.nonce)}getAIPMessageBuffer(j,$){let J=j.findIndex((z)=>z[0]===l.OP_RETURN),q=[];if(J===-1)q.push([l.OP_RETURN]),J=0;if($)for(let z of $)q.push(j[J+z]);else for(let z of j)q.push(z);return q}formatAIPOutput(j,$,J){let q=[C("|"),C(M),C("BITCOIN_ECDSA"),C($),C(J,"base64")];return[...j,...q]}}var{magicHash:qj}=H;class O extends V{key;idName;description;address;identityKey;constructor(j,$={}){super();this.key=j,this.address=j.toAddress(),this.idName="Member ID 1",this.description="",this.identityKey="",this.identityAttributes=this.parseAttributes($)}signMessage(j,$){let J=this.key,q=J.toAddress(),z=H.sign(j,J,"raw"),Q=new Jj(qj(j)),W=z.CalculateRecoveryFactor(J.toPublicKey(),Q),w=H.sign(j,J,"raw").toCompact(W,!0,"base64");return{address:q,signature:w}}signOpReturnWithAIP(j){let $=this.getAIPMessageBuffer(j),{address:J,signature:q}=this.signMessage($.flat());return this.formatAIPOutput($,J,q)}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=S.fromWif(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes||{},this.identityKey=j.identityKey}static fromMemberIdentity(j){let $=new O(S.fromWif(j.derivedPrivateKey));return $.import(j),$}static fromBackup(j){let $=new O(S.fromWif(j.wif)),J=JSON.parse($.decrypt(j.id));return $.import(J),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toWif(),address:this.address,identityAttributes:this.getAttributes(),identityKey:this.identityKey}}getEncryptionKey(){return{privKey:this.key.deriveChild(this.key.toPublicKey(),L),pubKey:this.key.deriveChild(this.key.toPublicKey(),L).toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}exportForBackup(j){let $=this.export(),J=this.encrypt(JSON.stringify($));return{wif:this.key.toWif(),id:J,...j&&{label:j},createdAt:new Date().toISOString()}}}var{toArray:G,toHex:k,toBase58:Zj,toUTF8:P,toBase64:D}=zj,{electrumDecrypt:b,electrumEncrypt:I}=Qj,{magicHash:o}=_;class R extends V{#j;#J=N;#Q="";#$;#q;#z;#Z;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){super();if(J){let Q=k(U.sha256(J,"utf8")),W=Y.getSigningPathFromHex(Q);this.#j=j.derive(W)}else this.#j=j;this.#Z=J,this.idName="ID 1",this.description="",this.#$=`${f}/0/0/0`,this.#q=`${f}/0/0/0`,this.#z=`${f}/0/0/1`;let q=this.#j.derive(this.#$);this.rootAddress=q.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);let z={...$};this.identityAttributes=this.parseAttributes(z),this.getApiData=x(this.#J,this.#Q)}set BAP_SERVER(j){this.#J=j}get BAP_SERVER(){return this.#J}set BAP_TOKEN(j){this.#Q=j}get BAP_TOKEN(){return this.#Q}deriveIdentityKey(j){let $=k(U.sha256(j,"utf8"));return Zj(U.ripemd160($,"hex"))}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let $ in j)if(!j[$].value||!j[$].nonce)throw new Error("Invalid identity attribute");return j||{}}parseStringUrns(j){let $={},J=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
5
- `);for(let q of J){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}getIdentityKey(){return this.identityKey}set rootPath(j){if(this.#j){let $=j;if(j.split("/").length<5)$=`${f}${j}`;if(!this.validatePath($))throw new Error(`invalid signing path given ${$}`);this.#$=$;let J=this.#j.derive($);this.rootAddress=J.pubKey.toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress),this.#q=$,this.#z=$}}get rootPath(){return this.#$}getRootPath(){return this.#$}set currentPath(j){let $=j;if(j.split("/").length<5)$=`${f}${j}`;if(!this.validatePath($))throw new Error("invalid signing path given");this.#q=this.#z,this.#z=$}get currentPath(){return this.#z}get previousPath(){return this.#q}get idSeed(){return this.#Z}incrementPath(){this.currentPath=Y.getNextPath(this.currentPath)}validatePath(j){if(j.match(/\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?/)){let $=j.split("/");if($.length===7&&Number($[1].replace("'",""))<=F&&Number($[2].replace("'",""))<=F&&Number($[3].replace("'",""))<=F&&Number($[4].replace("'",""))<=F&&Number($[5].replace("'",""))<=F&&Number($[6].replace("'",""))<=F)return!0}return!1}getInitialIdTransaction(){return this.getIdTransaction(this.#$)}getIdTransaction(j=""){if(this.#z===this.#$)throw new Error("Current path equals rootPath. ID was probably not initialized properly");let $=[G(X),G("ID"),G(this.identityKey),G(this.getCurrentAddress())];return this.signOpReturnWithAIP($,j||this.#q)}getAddress(j){return this.#j.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionKey(){let $=this.#j.derive(this.#$).derive(L).privKey;return{privKey:$,pubKey:$.toPublicKey()}}getEncryptionKeyType42(){let j=this.#j.derive(this.#$),$=j.privKey.deriveChild(j.toPublic().pubKey,L);return{privKey:$,pubKey:$.toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encrypt(j,$){let z=this.#j.derive(this.#$).derive(L).privKey.toPublicKey(),Q=$?E.fromString($):z;return D(I(G(j),Q,null))}decrypt(j,$){let q=this.#j.derive(this.#$).derive(L).privKey,z=void 0;if($)z=E.fromString($);return P(b(G(j,"base64"),q,z))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),z=q.toPublicKey(),Q=J?E.fromString(J):z;return D(I(G(j),Q,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),z=void 0;if(J)z=E.fromString(J);return P(b(G(j,"base64"),q,z))}getEncryptionPrivateKeyWithSeed(j){let $=k(U.sha256(j,"utf8")),J=Y.getSigningPathFromHex($);return this.#j.derive(this.#$).derive(J).privKey}getAttestation(j){let $=U.sha256(j,"utf8");return`bap:attest:${k($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=U.sha256(J,"utf8");return k(q)}signMessage(j,$){let J=$||this.#z,q=this.#j.derive(J).privKey,z=q.toAddress(),Q=_.sign(j,q,"raw"),W=new h(o(j)),w=Q.CalculateRecoveryFactor(q.toPublicKey(),W),v=_.sign(j,q,"raw").toCompact(w,!0,"base64");return{address:z,signature:v}}signMessageWithSeed(j,$){let J=k(U.sha256($,"utf8")),q=Y.getSigningPathFromHex(J),Q=this.#j.derive(this.#$).derive(q),W=Q.privKey.toPublicKey().toAddress(),w=G(j,"utf8"),v=_.sign(w,Q.privKey,"raw"),u=new h(o(w)),n=v.CalculateRecoveryFactor(Q.privKey.toPublicKey(),u),d=_.sign(w,Q.privKey,"raw").toCompact(n,!0,"base64");return{address:W,signature:d}}signOpReturnWithAIP(j,$=""){let J=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage(J.flat(),$);return this.formatAIPOutput(j,q,z)}async getIdSigningKeys(){let j=await this.getApiData("/signing-keys",{idKey:this.identityKey});return console.log("getIdSigningKeys",j),j}async getAttributeAttestations(j){let $=this.getAttestationHash(j),J=await this.getApiData("/attestation/get",{hash:$});return console.log("getAttestations",j,$,J),J}import(j){this.idName=j.name,this.description=j.description||"",this.identityKey=j.identityKey,this.#$=j.rootPath,this.rootAddress=j.rootAddress,this.#q=j.previousPath,this.#z=j.currentPath,this.#Z=("idSeed"in j?j.idSeed:"")||"",this.identityAttributes=this.parseAttributes(j.identityAttributes)}export(){return{name:this.idName,description:this.description,identityKey:this.identityKey,rootPath:this.#$,rootAddress:this.rootAddress,previousPath:this.#q,currentPath:this.#z,idSeed:this.#Z,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.#j.derive(this.#z).privKey;return{name:this.idName,description:this.description,derivedPrivateKey:j.toWif(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes(),identityKey:this.identityKey}}newId(){this.incrementPath();let j=this.#j.derive(this.#z).privKey;return new O(j)}exportMember(){let j=this.exportMemberBackup(),$=this.#j.derive(this.#z).privKey,J=D(I(G(JSON.stringify(j)),$.toPublicKey()));return{wif:j.derivedPrivateKey,encryptedData:J}}}var{toArray:Z,toUTF8:T,toBase64:y,toHex:B}=Gj,{electrumEncrypt:Fj,electrumDecrypt:Xj}=wj;class Cj{#j;#J={};#Q=N;#$="";#q="";getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No HDPrivateKey given");if(this.#j=Lj.fromString(j),$)this.#$=$;if(J)this.#Q=J;this.getApiData=x(this.#Q,this.#$)}get lastIdPath(){return this.#q}getPublicKey(j=""){if(j)return this.#j.derive(j).pubKey.toString();return this.#j.pubKey.toString()}getHdPublicKey(j=""){if(j)return this.#j.derive(j).toPublic().toString();return this.#j.toPublic().toString()}set BAP_SERVER(j){this.#Q=j;for(let $ in this.#J)this.#J[$].BAP_SERVER=j}get BAP_SERVER(){return this.#Q}set BAP_TOKEN(j){this.#$=j;for(let $ in this.#J)this.#J[$].BAP_TOKEN=j}get BAP_TOKEN(){return this.#$}checkIdBelongs(j){if(this.#j.derive(j.rootPath).pubKey.toAddress()!==j.rootAddress)throw new Error("ID does not belong to this private key");return!0}listIds(){return Object.keys(this.#J)}newId(j,$={},J=""){let q;if(!j)q=this.getNextValidPath();else q=j;let z=new R(this.#j,$,J);z.BAP_SERVER=this.#Q,z.BAP_TOKEN=this.#$,z.rootPath=q,z.currentPath=Y.getNextPath(q);let Q=z.getIdentityKey();return this.#J[Q]=z,this.#q=q,this.#J[Q]}removeId(j){delete this.#J[j]}getNextValidPath(){if(this.#q)return Y.getNextIdentityPath(this.#q);return`/0'/${Object.keys(this.#J).length}'/0'`}getId(j){return this.#J[j]||null}setId(j){this.checkIdBelongs(j),this.#J[j.getIdentityKey()]=j}importIds(j,$=!0){if($&&typeof j==="string"){this.importEncryptedIds(j);return}let J=j;if(!J.lastIdPath)throw new Error("ID cannot be imported as it is not complete");if(!J.ids)throw new Error(`ID data is not in the correct format: ${j}`);let q=j.lastIdPath;for(let z of J.ids){if(!z.identityKey||!z.identityAttributes||!z.rootAddress)throw new Error("ID cannot be imported as it is not complete");let Q=new R(this.#j,{},z.idSeed);if(Q.BAP_SERVER=this.#Q,Q.BAP_TOKEN=this.#$,Q.import(z),q==="")q=Q.currentPath;this.checkIdBelongs(Q),this.#J[Q.getIdentityKey()]=Q}this.#q=q}importEncryptedIds(j){let $=this.decrypt(j),J=JSON.parse($);if(Array.isArray(J)){console.log(`Importing old format:
6
- `,J),this.importOldIds(J);return}if(typeof J!=="object")throw new Error("decrypted, but found unrecognized identities format");this.importIds(J,!1)}importOldIds(j){for(let $ of j){let J=new R(this.#j,{},$.idSeed??"");J.BAP_SERVER=this.#Q,J.BAP_TOKEN=this.#$,J.import($),this.checkIdBelongs(J),this.#J[J.getIdentityKey()]=J,this.#q=J.currentPath}}exportIds(j,$=!0){let J={lastIdPath:this.#q,ids:[]},q=j||Object.keys(this.#J);for(let z of q){if(!this.#J[z])throw new Error(`Identity ${z} not found`);J.ids.push(this.#J[z].export())}if($)return this.encrypt(JSON.stringify(J));return J}exportId(j,$=!0){let J={lastIdPath:this.#q,ids:[]};if(J.ids.push(this.#J[j].export()),$)return this.encrypt(JSON.stringify(J));return J}encrypt(j){let $=this.#j.derive(L);return y(Fj(Z(j),$.pubKey,null))}decrypt(j){let $=this.#j.derive(L);return T(Xj(Z(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let z=this.getId($);if(!z)throw new Error("Could not find identity to attest with");let Q=this.getAttestationBuffer(j,J,q),{address:W,signature:w}=z.signMessage(Q);return this.createAttestationTransaction(j,J,W,w,q)}verifyAttestationWithAIP(j){if(!j.every((q)=>Array.isArray(q))||j[0][0]!==K.OP_RETURN||B(j[1])!==c)throw new Error("Not a valid BAP transaction");let $=B(j[7])==="44415441"?5:0,J={type:T(j[2]),hash:B(j[3]),sequence:T(j[4]),signingProtocol:T(j[7+$]),signingAddress:T(j[8+$]),signature:y(j[9+$])};if($&&j[3]===j[8])J.data=B(j[9]);console.log({attestation:J});try{let q=[];for(let z=0;z<6+$;z++)q.push(j[z]);J.verified=this.verifySignature(q.flat(),J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,z=""){let Q=[[K.OP_RETURN],Z(X),Z("ATTEST"),Z(j),Z(`${$}`),Z("|")];if(z)Q.push(Z(X),Z("DATA"),Z(j),Z(z),Z("|"));return Q.push(Z(M),Z("BITCOIN_ECDSA"),Z(J),Z(q,"base64")),console.log({elements:Q}),Q}getAttestationBuffer(j,$=0,J=""){let q=[[K.OP_RETURN],Z(X),Z("ATTEST"),Z(j),Z(`${$}`),Z("|")];if(J)q.push(Z(X),Z("DATA"),Z(j),Z(J),Z("|"));return q.flat()}verifySignature(j,$,J){let q;if(Array.isArray(j))q=j;else if(Buffer.isBuffer(j))q=[...j];else q=Z(j,"utf8");let z=Yj.fromCompact(J,"base64"),Q;for(let W=0;W<4;W++)try{if(Q=z.RecoverPublicKey(W,new Wj(g.magicHash(q))),g.verify(q,z,Q)&&Q.toAddress()===$)return!0}catch(w){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let Q=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(Q?.status==="success"&&Q?.result?.valid===!0)return!0;return!1}catch(Q){return console.error("API call failed:",Q),!1}}async isValidAttestationTransaction(j){if(this.verifyAttestationWithAIP(j))return this.getApiData("/attestation/valid",{tx:j});return!1}async getIdentityFromAddress(j){return this.getApiData("/identity/from-address",{address:j})}async getIdentity(j){return this.getApiData("/identity/get",{idKey:j})}async getAttestationsForHash(j){return this.getApiData("/attestations",{hash:j})}exportForBackup(j,$,J){return{ids:this.exportIds(),xprv:$||this.#j.toString(),mnemonic:J||"",...j&&{label:j},createdAt:new Date().toISOString()}}exportMemberForBackup(j,$){let J=this.#J[j];if(!J)throw new Error(`Identity ${j} not found`);let q=J.exportMember();return{wif:q.wif,id:q.encryptedData,...$&&{label:$},createdAt:new Date().toISOString()}}}export{O as MemberID,R as MasterID,Cj as BAP};
4
+ `);for(let q of J){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let $ in j)if(!j[$].value||!j[$].nonce)throw new Error("Invalid identity attribute");return j||{}}updateExistingAttribute(j,$){if(typeof $==="string"){this.identityAttributes[j].value=$;return}if(this.identityAttributes[j].value=$.value||"",$.nonce)this.identityAttributes[j].nonce=$.nonce}createNewAttribute(j,$){if(typeof $==="string"){this.addAttribute(j,$);return}this.addAttribute(j,$.value||"",$.nonce)}getAIPMessageBuffer(j,$){let J=j.findIndex((z)=>z[0]===h.OP_RETURN),q=[];if(J===-1)q.push([h.OP_RETURN]),J=0;if($)for(let z of $)q.push(j[J+z]);else for(let z of j)q.push(z);return q}formatAIPOutput(j,$,J){let q=[M("|"),M(R),M("BITCOIN_ECDSA"),M($),M(J,"base64")];return[...j,...q]}}var{magicHash:zj}=g;class O extends x{key;idName;description;address;identityKey;constructor(j,$={}){super();this.key=j,this.address=j.toAddress(),this.idName="Member ID 1",this.description="",this.identityKey="",this.identityAttributes=this.parseAttributes($)}signMessage(j,$){let J=this.key,q=J.toAddress(),z=g.sign(j,J,"raw"),Q=new qj(zj(j)),W=z.CalculateRecoveryFactor(J.toPublicKey(),Q),L=g.sign(j,J,"raw").toCompact(W,!0,"base64");return{address:q,signature:L}}signOpReturnWithAIP(j){let $=this.getAIPMessageBuffer(j),{address:J,signature:q}=this.signMessage($.flat());return this.formatAIPOutput($,J,q)}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=I.fromWif(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes||{},this.identityKey=j.identityKey}static fromMemberIdentity(j){let $=new O(I.fromWif(j.derivedPrivateKey));return $.import(j),$}static fromBackup(j){let $=new O(I.fromWif(j.wif)),J=JSON.parse($.decrypt(j.id));return $.import(J),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toWif(),address:this.address,identityAttributes:this.getAttributes(),identityKey:this.identityKey}}getEncryptionKey(){return{privKey:this.key.deriveChild(this.key.toPublicKey(),Y),pubKey:this.key.deriveChild(this.key.toPublicKey(),Y).toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}exportForBackup(j){let $=this.export(),J=this.encrypt(JSON.stringify($));return{wif:this.key.toWif(),id:J,...j&&{label:j},createdAt:new Date().toISOString()}}}var{toArray:X,toHex:V,toBase58:Lj,toUTF8:n,toBase64:v}=Qj,{electrumDecrypt:u,electrumEncrypt:A}=Zj,{magicHash:d}=E;class f extends x{#$;#j;#J;#Q=H;#W="";#q;#Z;#z;#L;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){super();if(j instanceof Wj)if(this.#J=!1,J){let z=V(U.sha256(J,"utf8")),Q=G.getSigningPathFromHex(z);this.#$=j.derive(Q)}else this.#$=j;else if(this.#J=!0,this.#j=j.rootPk,J){let z=V(U.sha256(J,"utf8"));this.#j=this.#j.deriveChild(this.#j.toPublicKey(),z)}if(this.#L=J,this.idName="ID 1",this.description="",this.#q=`${k}/0/0/0`,this.#Z=`${k}/0/0/0`,this.#z=`${k}/0/0/1`,this.#J){if(!this.#j)throw new Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#q);this.rootAddress=z.toPublicKey().toAddress()}else{if(!this.#$)throw new Error("HD private key not initialized");let z=this.#$.derive(this.#q);this.rootAddress=z.privKey.toPublicKey().toAddress()}this.identityKey=this.deriveIdentityKey(this.rootAddress);let q={...$};this.identityAttributes=this.parseAttributes(q),this.getApiData=T(this.#Q,this.#W)}set BAP_SERVER(j){this.#Q=j}get BAP_SERVER(){return this.#Q}set BAP_TOKEN(j){this.#W=j}get BAP_TOKEN(){return this.#W}deriveIdentityKey(j){let $=V(U.sha256(j,"utf8"));return Lj(U.ripemd160($,"hex"))}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let $ in j)if(!j[$].value||!j[$].nonce)throw new Error("Invalid identity attribute");return j||{}}parseStringUrns(j){let $={},J=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
5
+ `);for(let q of J){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}getIdentityKey(){return this.identityKey}set rootPath(j){if(this.#J){if(this.#q=j,!this.#j)throw new Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),j);this.rootAddress=$.toPublicKey().toAddress(),this.#Z=j,this.#z=j}else{let $=j;if(j.split("/").length<5)$=`${k}${j}`;if(!this.validatePath($))throw new Error(`invalid signing path given ${$}`);if(this.#q=$,!this.#$)throw new Error("HD private key not initialized");let J=this.#$.derive($);this.rootAddress=J.pubKey.toAddress(),this.#Z=$,this.#z=$}this.identityKey=this.deriveIdentityKey(this.rootAddress)}get rootPath(){return this.#q}getRootPath(){return this.#q}set currentPath(j){if(this.#J)this.#Z=this.#z,this.#z=j;else{let $=j;if(j.split("/").length<5)$=`${k}${j}`;if(!this.validatePath($))throw new Error("invalid signing path given");this.#Z=this.#z,this.#z=$}}get currentPath(){return this.#z}get previousPath(){return this.#Z}get idSeed(){return this.#L}incrementPath(){this.currentPath=G.getNextPath(this.currentPath)}validatePath(j){if(j.match(/\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?\/[0-9]{1,10}'?/)){let $=j.split("/");if($.length===7&&Number($[1].replace("'",""))<=F&&Number($[2].replace("'",""))<=F&&Number($[3].replace("'",""))<=F&&Number($[4].replace("'",""))<=F&&Number($[5].replace("'",""))<=F&&Number($[6].replace("'",""))<=F)return!0}return!1}getInitialIdTransaction(){return this.getIdTransaction(this.#q)}getIdTransaction(j=""){if(this.#z===this.#q)throw new Error("Current path equals rootPath. ID was probably not initialized properly");let $=[X(C),X("ID"),X(this.identityKey),X(this.getCurrentAddress())];return this.signOpReturnWithAIP($,j||this.#Z)}getAddress(j){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");return this.#j.deriveChild(this.#j.toPublicKey(),j).toPublicKey().toAddress()}if(!this.#$)throw new Error("HD private key not initialized");return this.#$.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionKey(){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),this.#q),q=J.deriveChild(J.toPublicKey(),Y);return{privKey:q,pubKey:q.toPublicKey()}}if(!this.#$)throw new Error("HD private key not initialized");let $=this.#$.derive(this.#q).derive(Y).privKey;return{privKey:$,pubKey:$.toPublicKey()}}getEncryptionKeyType42(){if(this.#J)return this.getEncryptionKey();if(!this.#$)throw new Error("HD private key not initialized");let j=this.#$.derive(this.#q),$=j.privKey.deriveChild(j.toPublic().pubKey,Y);return{privKey:$,pubKey:$.toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encrypt(j,$){let{privKey:J,pubKey:q}=this.getEncryptionKey(),z=$?S.fromString($):q;return v(A(X(j),z,null))}decrypt(j,$){let{privKey:J}=this.getEncryptionKey(),q=void 0;if($)q=S.fromString($);return n(u(X(j,"base64"),J,q))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),z=q.toPublicKey(),Q=J?S.fromString(J):z;return v(A(X(j),Q,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),z=void 0;if(J)z=S.fromString(J);return n(u(X(j,"base64"),q,z))}getEncryptionPrivateKeyWithSeed(j){let $=V(U.sha256(j,"utf8"));if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#q);return z.deriveChild(z.toPublicKey(),$)}if(!this.#$)throw new Error("HD private key not initialized");let J=G.getSigningPathFromHex($);return this.#$.derive(this.#q).derive(J).privKey}getAttestation(j){let $=U.sha256(j,"utf8");return`bap:attest:${V($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=U.sha256(J,"utf8");return V(q)}signMessage(j,$){let J=$||this.#z,q;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");q=this.#j.deriveChild(this.#j.toPublicKey(),J)}else{if(!this.#$)throw new Error("HD private key not initialized");q=this.#$.derive(J).privKey}let z=q.toAddress(),Q=E.sign(j,q,"raw"),W=new o(d(j)),L=Q.CalculateRecoveryFactor(q.toPublicKey(),W),w=E.sign(j,q,"raw").toCompact(L,!0,"base64");return{address:z,signature:w}}signMessageWithSeed(j,$){let J=V(U.sha256($,"utf8")),q;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let N=this.#j.deriveChild(this.#j.toPublicKey(),this.#q);q=N.deriveChild(N.toPublicKey(),J)}else{if(!this.#$)throw new Error("HD private key not initialized");let N=G.getSigningPathFromHex(J);q=this.#$.derive(this.#q).derive(N).privKey}let z=q.toPublicKey().toAddress(),Q=X(j,"utf8"),W=E.sign(Q,q,"raw"),L=new o(d(Q)),w=W.CalculateRecoveryFactor(q.toPublicKey(),L),B=E.sign(Q,q,"raw").toCompact(w,!0,"base64");return{address:z,signature:B}}signOpReturnWithAIP(j,$=""){let J=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage(J.flat(),$);return this.formatAIPOutput(j,q,z)}async getIdSigningKeys(){let j=await this.getApiData("/signing-keys",{idKey:this.identityKey});return console.log("getIdSigningKeys",j),j}async getAttributeAttestations(j){let $=this.getAttestationHash(j),J=await this.getApiData("/attestation/get",{hash:$});return console.log("getAttestations",j,$,J),J}import(j){this.idName=j.name,this.description=j.description||"",this.identityKey=j.identityKey,this.#q=j.rootPath,this.rootAddress=j.rootAddress,this.#Z=j.previousPath,this.#z=j.currentPath,this.#L=("idSeed"in j?j.idSeed:"")||"",this.identityAttributes=this.parseAttributes(j.identityAttributes)}export(){return{name:this.idName,description:this.description,identityKey:this.identityKey,rootPath:this.#q,rootAddress:this.rootAddress,previousPath:this.#Z,currentPath:this.#z,idSeed:this.#L,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");j=this.#j.deriveChild(this.#j.toPublicKey(),this.#z)}else{if(!this.#$)throw new Error("HD private key not initialized");j=this.#$.derive(this.#z).privKey}return{name:this.idName,description:this.description,derivedPrivateKey:j.toWif(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes(),identityKey:this.identityKey}}newId(){this.incrementPath();let j;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");j=this.#j.deriveChild(this.#j.toPublicKey(),this.#z)}else{if(!this.#$)throw new Error("HD private key not initialized");j=this.#$.derive(this.#z).privKey}return new O(j)}exportMember(){let j=this.exportMemberBackup(),$;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");$=this.#j.deriveChild(this.#j.toPublicKey(),this.#z)}else{if(!this.#$)throw new Error("HD private key not initialized");$=this.#$.derive(this.#z).privKey}let J=v(A(X(JSON.stringify(j)),$.toPublicKey()));return{wif:j.derivedPrivateKey,encryptedData:J}}}var{toArray:Z,toUTF8:_,toBase64:c,toHex:D}=Cj,{electrumEncrypt:y,electrumDecrypt:s}=Yj;class Uj{#$;#j;#J;#Q={};#W=H;#q="";#Z="";#z=0;getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No key source given");if(typeof j==="string")this.#$=Gj.fromString(j),this.#J=!1;else this.#j=Fj.fromWif(j.rootPk),this.#J=!0;if($)this.#q=$;if(J)this.#W=J;this.getApiData=T(this.#W,this.#q)}get lastIdPath(){return this.#Z}getPublicKey(j=""){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");if(j)return this.#j.deriveChild(this.#j.toPublicKey(),j).toPublicKey().toString();return this.#j.toPublicKey().toString()}if(!this.#$)throw new Error("HD private key not initialized");if(j)return this.#$.derive(j).pubKey.toString();return this.#$.pubKey.toString()}getHdPublicKey(j=""){if(this.#J)throw new Error("HD public keys are not available in Type 42 mode");if(!this.#$)throw new Error("HD private key not initialized");if(j)return this.#$.derive(j).toPublic().toString();return this.#$.toPublic().toString()}set BAP_SERVER(j){this.#W=j;for(let $ in this.#Q)this.#Q[$].BAP_SERVER=j}get BAP_SERVER(){return this.#W}set BAP_TOKEN(j){this.#q=j;for(let $ in this.#Q)this.#Q[$].BAP_TOKEN=j}get BAP_TOKEN(){return this.#q}checkIdBelongs(j){let $;if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");$=this.#j.deriveChild(this.#j.toPublicKey(),j.rootPath).toPublicKey().toAddress()}else{if(!this.#$)throw new Error("HD private key not initialized");$=this.#$.derive(j.rootPath).pubKey.toAddress()}if($!==j.rootAddress)throw new Error("ID does not belong to this private key");return!0}listIds(){return Object.keys(this.#Q)}newId(j,$,J={},q=""){let z,Q,W;if(typeof j==="object"||j===void 0||typeof j==="string"&&j.startsWith("/"))Q=typeof j==="string"?j:void 0,W=typeof j==="object"?j:typeof $==="object"?$:{},z="Default Identity";else z=j,Q=typeof $==="string"?$:void 0,W=typeof $==="object"?$:J;let L;if(Q)L=Q;else if(this.#J)L=`bap:${this.#z}`,this.#z++;else L=this.getNextValidPath();let w;if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");w=new f({rootPk:this.#j},W,q)}else{if(!this.#$)throw new Error("HD private key not initialized");w=new f(this.#$,W,q)}if(w.BAP_SERVER=this.#W,w.BAP_TOKEN=this.#q,w.idName=z,w.rootPath=L,this.#J)w.currentPath=L;else w.currentPath=G.getNextPath(L);let B=w.getIdentityKey();return this.#Q[B]=w,this.#Z=L,this.#Q[B]}removeId(j){delete this.#Q[j]}getNextValidPath(){if(this.#Z)return G.getNextIdentityPath(this.#Z);return`/0'/${Object.keys(this.#Q).length}'/0'`}newIdWithCounter(j,$=`Identity ${j}`){if(!this.#J)throw new Error("newIdWithCounter only works in Type 42 mode");let J=`bap:${j}`;return this.newId($,J)}getId(j){return this.#Q[j]||null}setId(j){this.checkIdBelongs(j),this.#Q[j.getIdentityKey()]=j}importIds(j,$=!0){if($&&typeof j==="string"){this.importEncryptedIds(j);return}let J=j;if(!J.lastIdPath)throw new Error("ID cannot be imported as it is not complete");if(!J.ids)throw new Error(`ID data is not in the correct format: ${j}`);let q=j.lastIdPath;for(let z of J.ids){if(!z.identityKey||!z.identityAttributes||!z.rootAddress)throw new Error("ID cannot be imported as it is not complete");let Q;if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");Q=new f({rootPk:this.#j},{},z.idSeed)}else{if(!this.#$)throw new Error("HD private key not initialized");Q=new f(this.#$,{},z.idSeed)}if(Q.BAP_SERVER=this.#W,Q.BAP_TOKEN=this.#q,Q.import(z),q==="")q=Q.currentPath;if(this.checkIdBelongs(Q),this.#Q[Q.getIdentityKey()]=Q,this.#J&&Q.rootPath.startsWith("bap:")){let W=Q.rootPath.split(":");if(W.length>=2){let L=parseInt(W[1],10);if(!isNaN(L))this.#z=Math.max(this.#z,L+1)}}}this.#Z=q}importEncryptedIds(j){let $=this.decrypt(j),J=JSON.parse($);if(Array.isArray(J)){console.log(`Importing old format:
6
+ `,J),this.importOldIds(J);return}if(typeof J!=="object")throw new Error("decrypted, but found unrecognized identities format");this.importIds(J,!1)}importOldIds(j){for(let $ of j){let J;if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");J=new f({rootPk:this.#j},{},$.idSeed??"")}else{if(!this.#$)throw new Error("HD private key not initialized");J=new f(this.#$,{},$.idSeed??"")}J.BAP_SERVER=this.#W,J.BAP_TOKEN=this.#q,J.import($),this.checkIdBelongs(J),this.#Q[J.getIdentityKey()]=J,this.#Z=J.currentPath}}exportIds(j,$=!0){let J={lastIdPath:this.#Z,ids:[]},q=j||Object.keys(this.#Q);for(let z of q){if(!this.#Q[z])throw new Error(`Identity ${z} not found`);J.ids.push(this.#Q[z].export())}if($)return this.encrypt(JSON.stringify(J));return J}exportId(j,$=!0){let J={lastIdPath:this.#Z,ids:[]};if(J.ids.push(this.#Q[j].export()),$)return this.encrypt(JSON.stringify(J));return J}encrypt(j){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),Y);return c(y(Z(j),J.toPublicKey(),null))}if(!this.#$)throw new Error("HD private key not initialized");let $=this.#$.derive(Y);return c(y(Z(j),$.pubKey,null))}decrypt(j){if(this.#J){if(!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),Y);return _(s(Z(j,"base64"),J))}if(!this.#$)throw new Error("HD private key not initialized");let $=this.#$.derive(Y);return _(s(Z(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let z=this.getId($);if(!z)throw new Error("Could not find identity to attest with");let Q=this.getAttestationBuffer(j,J,q),{address:W,signature:L}=z.signMessage(Q);return this.createAttestationTransaction(j,J,W,L,q)}verifyAttestationWithAIP(j){if(!j.every((q)=>Array.isArray(q))||j[0][0]!==K.OP_RETURN||D(j[1])!==p)throw new Error("Not a valid BAP transaction");let $=D(j[7])==="44415441"?5:0,J={type:_(j[2]),hash:D(j[3]),sequence:_(j[4]),signingProtocol:_(j[7+$]),signingAddress:_(j[8+$]),signature:c(j[9+$])};if($&&j[3]===j[8])J.data=D(j[9]);console.log({attestation:J});try{let q=[];for(let z=0;z<6+$;z++)q.push(j[z]);J.verified=this.verifySignature(q.flat(),J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,z=""){let Q=[[K.OP_RETURN],Z(C),Z("ATTEST"),Z(j),Z(`${$}`),Z("|")];if(z)Q.push(Z(C),Z("DATA"),Z(j),Z(z),Z("|"));return Q.push(Z(R),Z("BITCOIN_ECDSA"),Z(J),Z(q,"base64")),console.log({elements:Q}),Q}getAttestationBuffer(j,$=0,J=""){let q=[[K.OP_RETURN],Z(C),Z("ATTEST"),Z(j),Z(`${$}`),Z("|")];if(J)q.push(Z(C),Z("DATA"),Z(j),Z(J),Z("|"));return q.flat()}verifySignature(j,$,J){let q;if(Array.isArray(j))q=j;else if(Buffer.isBuffer(j))q=[...j];else q=Z(j,"utf8");let z=Xj.fromCompact(J,"base64"),Q;for(let W=0;W<4;W++)try{if(Q=z.RecoverPublicKey(W,new wj(l.magicHash(q))),l.verify(q,z,Q)&&Q.toAddress()===$)return!0}catch(L){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let Q=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(Q?.status==="success"&&Q?.result?.valid===!0)return!0;return!1}catch(Q){return console.error("API call failed:",Q),!1}}async isValidAttestationTransaction(j){if(this.verifyAttestationWithAIP(j))return this.getApiData("/attestation/valid",{tx:j});return!1}async getIdentityFromAddress(j){return this.getApiData("/identity/from-address",{address:j})}async getIdentity(j){return this.getApiData("/identity/get",{idKey:j})}async getAttestationsForHash(j){return this.getApiData("/attestations",{hash:j})}exportForBackup(j,$,J){let z={ids:this.exportIds(),...j&&{label:j},createdAt:new Date().toISOString()};if(this.#J){if(!this.#j)throw new Error("Type 42 parameters not initialized");return{...z,rootPk:this.#j.toWif()}}if(!this.#$)throw new Error("HD private key not initialized");return{...z,xprv:$||this.#$.toString(),mnemonic:J||""}}exportMemberForBackup(j,$){let J=this.#Q[j];if(!J)throw new Error(`Identity ${j} not found`);let q=J.exportMember();return{wif:q.wif,id:q.encryptedData,...$&&{label:$},createdAt:new Date().toISOString()}}}export{O as MemberID,f as MasterID,Uj as BAP};
7
7
 
8
- //# debugId=2FD0340A6F449AF364756E2164756E21
8
+ //# debugId=E00B799163EC32CD64756E2164756E21