bsv-bap 0.1.1 → 0.1.2

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/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { type APIFetcher } from "./api";
2
2
  import type { AttestationValidResponse, GetAttestationResponse, GetIdentityByAddressResponse, GetIdentityResponse } from "./apiTypes";
3
3
  import { MasterID } from "./MasterID";
4
4
  import type { Attestation, Identity, IdentityAttributes, OldIdentity, PathPrefix } from "./interface";
5
+ import { MemberID } from "./MemberID";
5
6
  type Identities = {
6
7
  lastIdPath: string;
7
8
  ids: Identity[];
@@ -238,5 +239,5 @@ export declare class BAP {
238
239
  */
239
240
  getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse>;
240
241
  }
241
- export { MasterID };
242
+ export { MasterID, MemberID };
242
243
  export type { Attestation, Identity, IdentityAttributes, PathPrefix };
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{BSM as N,BigNumber as n,ECIES as d,HD as s,Signature as r}from"@bsv/sdk";import{Utils as i}from"@bsv/sdk";var l=async(j,$,J,q)=>{let Q=`${J}${j}`;return(await fetch(Q,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},U=(j,$)=>async(J,q)=>{return l(J,q,j,$)};var Y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",H=`0x${Buffer.from("1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT").toString("hex")}`,R="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",qj=`0x${Buffer.from("15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva").toString("hex")}`,x="https://api.sigmaidentity.com/v1",F=2147483647,C="m/424150'/0'/0'",G="m/424150'/2147483647'/2147483647'";import{BSM as M,Utils as h,BigNumber as S,ECIES as y,Hash as X,PublicKey as _}from"@bsv/sdk";import{randomBytes as b}from"crypto";var W={hexEncode(j){return`0x${Buffer.from(j).toString("hex")}`},hexDecode(j,$="utf8"){return Buffer.from(j.replace("0x",""),"hex").toString($)},getRandomString(j=32){return b(j).toString("hex")},isHex(j){if(typeof j!=="string")return!1;return/^[0-9a-fA-F]+$/.test(j)},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let Q=2147483647;for(let z of q){let Z=Number(`0x${z}`);if(Z>Q)Z-=Q;J+=`/${Z}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=Q+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=Q+(q?"'":""),$.join("/")}};import{BSM as T,BigNumber as p,PrivateKey as D,Utils as P}from"@bsv/sdk";var{toHex:wj,toBase58:Yj,toArray:B}=P,{magicHash:o}=T;class V{key;identityAttributes;address;idName;description;constructor(j,$={}){this.key=j,this.identityAttributes=typeof $==="string"?this.parseStringUrns($):$,this.address=this.key.toAddress(),this.idName="Member ID 1",this.description=""}signMessage(j){let $=typeof j==="string"?Buffer.from(j):j,J=this.key,q=J.toPublicKey().toString(),Q=T.sign(B($),J,"raw"),z=new p(o(B($,"utf8"))),Z=Q.CalculateRecoveryFactor(J.toPublicKey(),z),L=T.sign(B($),J,"raw").toCompact(Z,!0,"base64");return{address:q,signature:L}}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=D.fromString(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes}static fromImport(j){let $=new V(D.fromString(j.derivedPrivateKey));return $.import(j),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toString(),address:this.address,identityAttributes:this.identityAttributes}}parseStringUrns(j){let $={},J=j.replace(/^[ \t]+/gm,"").trim().split(`
3
- `);for(let q of J){let Q=q.split(":");if(Q.length>=6&&Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id")$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}}var{toArray:w,toHex:O,toBase58:u,toUTF8:I,toBase64:A}=h,{electrumDecrypt:K,electrumEncrypt:m}=y,{magicHash:g}=M;class f{#j;#J=x;#Q="";#$;#q;#z;#W;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){if(this.#W=J,J){let z=O(X.sha256(J,"utf8")),Z=W.getSigningPathFromHex(z);this.#j=j.derive(Z)}else this.#j=j;this.idName="ID 1",this.description="",this.#$=`${C}/0/0/0`,this.#q=`${C}/0/0/0`,this.#z=`${C}/0/0/1`;let q=this.#j.derive(this.#$);this.rootAddress=q.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);let Q={...$};this.identityAttributes=this.parseAttributes(Q),this.getApiData=U(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 $=O(X.sha256(j,"utf8"));return u(X.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(`
2
+ import{BSM as N,BigNumber as n,ECIES as d,HD as s,Signature as r}from"@bsv/sdk";import{Utils as i}from"@bsv/sdk";var l=async(j,$,J,q)=>{let Q=`${J}${j}`;return(await fetch(Q,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},R=(j,$)=>async(J,q)=>{return l(J,q,j,$)};var Y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",H=`0x${Buffer.from("1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT").toString("hex")}`,x="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",qj=`0x${Buffer.from("15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva").toString("hex")}`,V="https://api.sigmaidentity.com/v1",F=2147483647,C="m/424150'/0'/0'",G="m/424150'/2147483647'/2147483647'";import{BSM as M,Utils as h,BigNumber as D,ECIES as y,Hash as X,PublicKey as _}from"@bsv/sdk";import{randomBytes as b}from"crypto";var W={hexEncode(j){return`0x${Buffer.from(j).toString("hex")}`},hexDecode(j,$="utf8"){return Buffer.from(j.replace("0x",""),"hex").toString($)},getRandomString(j=32){return b(j).toString("hex")},isHex(j){if(typeof j!=="string")return!1;return/^[0-9a-fA-F]+$/.test(j)},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let Q=2147483647;for(let z of q){let Z=Number(`0x${z}`);if(Z>Q)Z-=Q;J+=`/${Z}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=Q+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=Q+(q?"'":""),$.join("/")}};import{BSM as T,BigNumber as p,PrivateKey as S,Utils as P}from"@bsv/sdk";var{toHex:wj,toBase58:Yj,toArray:B}=P,{magicHash:o}=T;class f{key;identityAttributes;address;idName;description;constructor(j,$={}){this.key=j,this.identityAttributes=typeof $==="string"?this.parseStringUrns($):$,this.address=this.key.toAddress(),this.idName="Member ID 1",this.description=""}signMessage(j){let $=typeof j==="string"?Buffer.from(j):j,J=this.key,q=J.toPublicKey().toString(),Q=T.sign(B($),J,"raw"),z=new p(o(B($,"utf8"))),Z=Q.CalculateRecoveryFactor(J.toPublicKey(),z),L=T.sign(B($),J,"raw").toCompact(Z,!0,"base64");return{address:q,signature:L}}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=S.fromString(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes}static fromImport(j){let $=new f(S.fromString(j.derivedPrivateKey));return $.import(j),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toString(),address:this.address,identityAttributes:this.identityAttributes}}parseStringUrns(j){let $={},J=j.replace(/^[ \t]+/gm,"").trim().split(`
3
+ `);for(let q of J){let Q=q.split(":");if(Q.length>=6&&Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id")$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}}var{toArray:w,toHex:O,toBase58:u,toUTF8:I,toBase64:A}=h,{electrumDecrypt:K,electrumEncrypt:g}=y,{magicHash:m}=M;class U{#j;#J=V;#Q="";#$;#q;#z;#W;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){if(this.#W=J,J){let z=O(X.sha256(J,"utf8")),Z=W.getSigningPathFromHex(z);this.#j=j.derive(Z)}else this.#j=j;this.idName="ID 1",this.description="",this.#$=`${C}/0/0/0`,this.#q=`${C}/0/0/0`,this.#z=`${C}/0/0/1`;let q=this.#j.derive(this.#$);this.rootAddress=q.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);let Q={...$};this.identityAttributes=this.parseAttributes(Q),this.getApiData=R(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 $=O(X.sha256(j,"utf8"));return u(X.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(`
4
4
  `);for(let q of J){let z=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(z[0]==="urn"&&z[1]==="bap"&&z[2]==="id"&&z[3]&&z[4]&&z[5])$[z[3]]={value:z[4],nonce:z[5]}}return $}getIdentityKey(){return this.identityKey}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,$)}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)}unsetAttribute(j){delete this.identityAttributes[j]}getAttributeUrns(){let j="";for(let $ in this.identityAttributes){let J=this.getAttributeUrn($);if(J)j+=`${J}
5
- `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}addAttribute(j,$,J=""){let q=J;if(!J)q=W.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}set rootPath(j){if(this.#j){let $=j;if(j.split("/").length<5)$=`${C}${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)$=`${C}${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.#W}incrementPath(){this.currentPath=W.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 $=[Buffer.from(Y).toString("hex"),Buffer.from("ID").toString("hex"),Buffer.from(this.identityKey).toString("hex"),Buffer.from(this.getCurrentAddress()).toString("hex")];return this.signOpReturnWithAIP($,j||this.#q)}getAddress(j){return this.#j.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionPublicKey(){return this.#j.derive(this.#$).derive(G).privKey.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString("hex")}encrypt(j,$){let Q=this.#j.derive(this.#$).derive(G).privKey.toPublicKey(),z=$?_.fromString($):Q;return A(m(w(j),z,null))}decrypt(j,$){let q=this.#j.derive(this.#$).derive(G).privKey,Q=void 0;if($)Q=_.fromString($);return I(K(w(j,"base64"),q,Q))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=q.toPublicKey(),z=J?_.fromString(J):Q;return A(m(w(j),z,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=void 0;if(J)Q=_.fromString(J);return I(K(w(j,"base64"),q,Q))}getEncryptionPrivateKeyWithSeed(j){let $=O(X.sha256(j,"utf8")),J=W.getSigningPathFromHex($);return this.#j.derive(this.#$).derive(J).privKey}getAttestation(j){let $=X.sha256(j,"utf8");return`bap:attest:${O($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=X.sha256(J,"utf8");return O(q)}signMessage(j,$=""){let J;if(!(j instanceof Buffer))J=Buffer.from(j);else J=j;let q=$||this.#z,Q=this.#j.derive(q).privKey,z=Q.toAddress(),Z=M.sign(w(j),Q,"raw"),L=new S(g(w(j,"utf8"))),k=Z.CalculateRecoveryFactor(Q.toPublicKey(),L),E=M.sign(w(J),Q,"raw").toCompact(k,!0,"base64");return{address:z,signature:E}}signMessageWithSeed(j,$){let J=O(X.sha256($,"utf8")),q=W.getSigningPathFromHex(J),z=this.#j.derive(this.#$).derive(q),Z=z.privKey.toPublicKey().toAddress(),L=M.sign(w(j),z.privKey,"raw"),k=new S(g(w(j,"utf8"))),E=L.CalculateRecoveryFactor(z.privKey.toPublicKey(),k),c=M.sign(w(Buffer.from(j)),z.privKey,"raw").toCompact(E,!0,"base64");return{address:Z,signature:c}}signOpReturnWithAIP(j,$="",J="hex"){let q=this.getAIPMessageBuffer(j),{address:Q,signature:z}=this.signMessage(q,$);return j.concat([Buffer.from("|").toString(J),Buffer.from(R).toString(J),Buffer.from("BITCOIN_ECDSA").toString(J),Buffer.from(Q).toString(J),Buffer.from(z,"base64").toString(J)])}getAIPMessageBuffer(j){let $=[];if(j[0].replace("0x","")!=="6a")$.push(Buffer.from("6a","hex"));for(let J of j)$.push(Buffer.from(J.replace("0x",""),"hex"));return $.push(Buffer.from("|")),Buffer.concat([...$])}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.#W=("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.#W,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.#j.derive(this.#z).privKey;return{name:this.idName,description:this.description,derivedPrivateKey:j.toString(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes()}}newId(){this.incrementPath();let j=this.#j.derive(this.#z).privKey;return new V(j,this.getAttributes())}}var{toArray:v,toUTF8:a,toBase64:e}=i,{electrumEncrypt:t,electrumDecrypt:jj}=d;class $j{#j;#J={};#Q=x;#$="";#q="";getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No HDPrivateKey given");if(this.#j=s.fromString(j),$)this.#$=$;if(J)this.#Q=J;this.getApiData=U(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 Q=new f(this.#j,$,J);Q.BAP_SERVER=this.#Q,Q.BAP_TOKEN=this.#$,Q.rootPath=q,Q.currentPath=W.getNextPath(q);let z=Q.getIdentityKey();return this.#J[z]=Q,this.#q=q,this.#J[z]}removeId(j){delete this.#J[j]}getNextValidPath(){if(this.#q)return W.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 Q of J.ids){if(!Q.identityKey||!Q.identityAttributes||!Q.rootAddress)throw new Error("ID cannot be imported as it is not complete");let z=new f(this.#j,{},Q.idSeed);if(z.BAP_SERVER=this.#Q,z.BAP_TOKEN=this.#$,z.import(Q),q==="")q=z.currentPath;this.checkIdBelongs(z),this.#J[z.getIdentityKey()]=z}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 f(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 Q of q){if(!this.#J[Q])throw new Error(`Identity ${Q} not found`);J.ids.push(this.#J[Q].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(G);return e(t(v(j),$.pubKey,null))}decrypt(j){let $=this.#j.derive(G);return a(jj(v(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let Q=this.getId($);if(!Q)throw new Error("Could not find identity to attest with");let z=this.getAttestationBuffer(j,J,q),{address:Z,signature:L}=Q.signMessage(z);return this.createAttestationTransaction(j,J,Z,L,q)}verifyAttestationWithAIP(j){if(!Array.isArray(j)||j[0]!=="0x6a"||j[1]!==H)throw new Error("Not a valid BAP transaction");let $=j[7]==="0x44415441"?5:0,J={type:W.hexDecode(j[2]),hash:W.hexDecode(j[3]),sequence:W.hexDecode(j[4]),signingProtocol:W.hexDecode(j[7+$]),signingAddress:W.hexDecode(j[8+$]),signature:W.hexDecode(j[9+$],"base64")};if($&&j[3]===j[8])J.data=W.hexDecode(j[9]);try{let q=[];for(let z=0;z<6+$;z++)q.push(Buffer.from(j[z].replace("0x",""),"hex"));let Q=Buffer.concat(q);J.verified=this.verifySignature(Q,J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,Q=""){let z=["0x6a",W.hexEncode(Y)];if(z.push(W.hexEncode("ATTEST")),z.push(W.hexEncode(j)),z.push(W.hexEncode(`${$}`)),z.push("0x7c"),Q)z.push(W.hexEncode(Y)),z.push(W.hexEncode("DATA")),z.push(W.hexEncode(j)),z.push(W.hexEncode(Q)),z.push("0x7c");return z.push(W.hexEncode(R)),z.push(W.hexEncode("BITCOIN_ECDSA")),z.push(W.hexEncode(J)),z.push(`0x${Buffer.from(q,"base64").toString("hex")}`),z}getAttestationBuffer(j,$=0,J=""){let q=Buffer.from("");if(J)q=Buffer.concat([Buffer.from(Y),Buffer.from("DATA"),Buffer.from(j),Buffer.from(J),Buffer.from("7c","hex")]);return Buffer.concat([Buffer.from("6a","hex"),Buffer.from(Y),Buffer.from("ATTEST"),Buffer.from(j),Buffer.from(`${$}`),Buffer.from("7c","hex"),q])}verifySignature(j,$,J){let q=Buffer.isBuffer(j)?j:Buffer.from(j),Q=r.fromCompact(J,"base64"),z,Z=v(q.toString("hex"),"hex");for(let L=0;L<4;L++)try{if(z=Q.RecoverPublicKey(L,new n(N.magicHash(Z))),N.verify(Z,Q,z)&&z.toAddress()===$)return!0}catch(k){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let z=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(z?.status==="success"&&z?.result?.valid===!0)return!0;return!1}catch(z){return console.error("API call failed:",z),!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})}}export{f as MasterID,$j as BAP};
5
+ `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}addAttribute(j,$,J=""){let q=J;if(!J)q=W.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}set rootPath(j){if(this.#j){let $=j;if(j.split("/").length<5)$=`${C}${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)$=`${C}${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.#W}incrementPath(){this.currentPath=W.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 $=[Buffer.from(Y).toString("hex"),Buffer.from("ID").toString("hex"),Buffer.from(this.identityKey).toString("hex"),Buffer.from(this.getCurrentAddress()).toString("hex")];return this.signOpReturnWithAIP($,j||this.#q)}getAddress(j){return this.#j.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionPublicKey(){return this.#j.derive(this.#$).derive(G).privKey.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString("hex")}encrypt(j,$){let Q=this.#j.derive(this.#$).derive(G).privKey.toPublicKey(),z=$?_.fromString($):Q;return A(g(w(j),z,null))}decrypt(j,$){let q=this.#j.derive(this.#$).derive(G).privKey,Q=void 0;if($)Q=_.fromString($);return I(K(w(j,"base64"),q,Q))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=q.toPublicKey(),z=J?_.fromString(J):Q;return A(g(w(j),z,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=void 0;if(J)Q=_.fromString(J);return I(K(w(j,"base64"),q,Q))}getEncryptionPrivateKeyWithSeed(j){let $=O(X.sha256(j,"utf8")),J=W.getSigningPathFromHex($);return this.#j.derive(this.#$).derive(J).privKey}getAttestation(j){let $=X.sha256(j,"utf8");return`bap:attest:${O($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=X.sha256(J,"utf8");return O(q)}signMessage(j,$=""){let J;if(!(j instanceof Buffer))J=Buffer.from(j);else J=j;let q=$||this.#z,Q=this.#j.derive(q).privKey,z=Q.toAddress(),Z=M.sign(w(j),Q,"raw"),L=new D(m(w(j,"utf8"))),k=Z.CalculateRecoveryFactor(Q.toPublicKey(),L),E=M.sign(w(J),Q,"raw").toCompact(k,!0,"base64");return{address:z,signature:E}}signMessageWithSeed(j,$){let J=O(X.sha256($,"utf8")),q=W.getSigningPathFromHex(J),z=this.#j.derive(this.#$).derive(q),Z=z.privKey.toPublicKey().toAddress(),L=M.sign(w(j),z.privKey,"raw"),k=new D(m(w(j,"utf8"))),E=L.CalculateRecoveryFactor(z.privKey.toPublicKey(),k),c=M.sign(w(Buffer.from(j)),z.privKey,"raw").toCompact(E,!0,"base64");return{address:Z,signature:c}}signOpReturnWithAIP(j,$="",J="hex"){let q=this.getAIPMessageBuffer(j),{address:Q,signature:z}=this.signMessage(q,$);return j.concat([Buffer.from("|").toString(J),Buffer.from(x).toString(J),Buffer.from("BITCOIN_ECDSA").toString(J),Buffer.from(Q).toString(J),Buffer.from(z,"base64").toString(J)])}getAIPMessageBuffer(j){let $=[];if(j[0].replace("0x","")!=="6a")$.push(Buffer.from("6a","hex"));for(let J of j)$.push(Buffer.from(J.replace("0x",""),"hex"));return $.push(Buffer.from("|")),Buffer.concat([...$])}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.#W=("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.#W,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.#j.derive(this.#z).privKey;return{name:this.idName,description:this.description,derivedPrivateKey:j.toString(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes()}}newId(){this.incrementPath();let j=this.#j.derive(this.#z).privKey;return new f(j,this.getAttributes())}}var{toArray:v,toUTF8:a,toBase64:e}=i,{electrumEncrypt:t,electrumDecrypt:jj}=d;class $j{#j;#J={};#Q=V;#$="";#q="";getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No HDPrivateKey given");if(this.#j=s.fromString(j),$)this.#$=$;if(J)this.#Q=J;this.getApiData=R(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 Q=new U(this.#j,$,J);Q.BAP_SERVER=this.#Q,Q.BAP_TOKEN=this.#$,Q.rootPath=q,Q.currentPath=W.getNextPath(q);let z=Q.getIdentityKey();return this.#J[z]=Q,this.#q=q,this.#J[z]}removeId(j){delete this.#J[j]}getNextValidPath(){if(this.#q)return W.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 Q of J.ids){if(!Q.identityKey||!Q.identityAttributes||!Q.rootAddress)throw new Error("ID cannot be imported as it is not complete");let z=new U(this.#j,{},Q.idSeed);if(z.BAP_SERVER=this.#Q,z.BAP_TOKEN=this.#$,z.import(Q),q==="")q=z.currentPath;this.checkIdBelongs(z),this.#J[z.getIdentityKey()]=z}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 U(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 Q of q){if(!this.#J[Q])throw new Error(`Identity ${Q} not found`);J.ids.push(this.#J[Q].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(G);return e(t(v(j),$.pubKey,null))}decrypt(j){let $=this.#j.derive(G);return a(jj(v(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let Q=this.getId($);if(!Q)throw new Error("Could not find identity to attest with");let z=this.getAttestationBuffer(j,J,q),{address:Z,signature:L}=Q.signMessage(z);return this.createAttestationTransaction(j,J,Z,L,q)}verifyAttestationWithAIP(j){if(!Array.isArray(j)||j[0]!=="0x6a"||j[1]!==H)throw new Error("Not a valid BAP transaction");let $=j[7]==="0x44415441"?5:0,J={type:W.hexDecode(j[2]),hash:W.hexDecode(j[3]),sequence:W.hexDecode(j[4]),signingProtocol:W.hexDecode(j[7+$]),signingAddress:W.hexDecode(j[8+$]),signature:W.hexDecode(j[9+$],"base64")};if($&&j[3]===j[8])J.data=W.hexDecode(j[9]);try{let q=[];for(let z=0;z<6+$;z++)q.push(Buffer.from(j[z].replace("0x",""),"hex"));let Q=Buffer.concat(q);J.verified=this.verifySignature(Q,J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,Q=""){let z=["0x6a",W.hexEncode(Y)];if(z.push(W.hexEncode("ATTEST")),z.push(W.hexEncode(j)),z.push(W.hexEncode(`${$}`)),z.push("0x7c"),Q)z.push(W.hexEncode(Y)),z.push(W.hexEncode("DATA")),z.push(W.hexEncode(j)),z.push(W.hexEncode(Q)),z.push("0x7c");return z.push(W.hexEncode(x)),z.push(W.hexEncode("BITCOIN_ECDSA")),z.push(W.hexEncode(J)),z.push(`0x${Buffer.from(q,"base64").toString("hex")}`),z}getAttestationBuffer(j,$=0,J=""){let q=Buffer.from("");if(J)q=Buffer.concat([Buffer.from(Y),Buffer.from("DATA"),Buffer.from(j),Buffer.from(J),Buffer.from("7c","hex")]);return Buffer.concat([Buffer.from("6a","hex"),Buffer.from(Y),Buffer.from("ATTEST"),Buffer.from(j),Buffer.from(`${$}`),Buffer.from("7c","hex"),q])}verifySignature(j,$,J){let q=Buffer.isBuffer(j)?j:Buffer.from(j),Q=r.fromCompact(J,"base64"),z,Z=v(q.toString("hex"),"hex");for(let L=0;L<4;L++)try{if(z=Q.RecoverPublicKey(L,new n(N.magicHash(Z))),N.verify(Z,Q,z)&&z.toAddress()===$)return!0}catch(k){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let z=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(z?.status==="success"&&z?.result?.valid===!0)return!0;return!1}catch(z){return console.error("API call failed:",z),!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})}}export{f as MemberID,U as MasterID,$j as BAP};
7
7
 
8
- //# debugId=63CF71C289EEF0B864756E2164756E21
8
+ //# debugId=6A60A376E5A4A51E64756E2164756E21
@@ -2,14 +2,14 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/api.ts", "../src/constants.ts", "../src/MasterID.ts", "../src/utils.ts", "../src/MemberID.ts"],
4
4
  "sourcesContent": [
5
- "import { BSM, BigNumber, ECIES, HD, type PublicKey, Signature } from \"@bsv/sdk\";\n\nimport { Utils as BSVUtils } from \"@bsv/sdk\";\nimport { type APIFetcher, apiFetcher } from \"./api\";\nimport type { AttestationValidResponse, GetAttestationResponse, GetIdentityByAddressResponse, GetIdentityResponse } from \"./apiTypes\";\nimport {\n AIP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS_HEX,\n BAP_SERVER,\n ENCRYPTION_PATH,\n} from \"./constants\";\nimport { MasterID } from \"./MasterID\";\nimport type { Attestation, Identity, IdentityAttributes, OldIdentity, PathPrefix } from \"./interface\";\nimport { Utils } from \"./utils\";\nconst { toArray, toUTF8, toBase64 } = BSVUtils;\nconst { electrumEncrypt, electrumDecrypt } = ECIES;\n\ntype Identities = { lastIdPath: string; ids: Identity[] };\n\n\n/**\n * BAP class\n *\n * Creates an instance of the BAP class and uses the given HDPrivateKey for all BAP operations.\n *\n * @param HDPrivateKey\n */\nexport class BAP {\n #HDPrivateKey;\n #ids: { [key: string]: MasterID } = {};\n #BAP_SERVER = BAP_SERVER;\n #BAP_TOKEN = \"\";\n #lastIdPath = \"\";\n getApiData: APIFetcher;\n\n constructor(HDPrivateKey: string, token = \"\", server = \"\") {\n if (!HDPrivateKey) {\n throw new Error(\"No HDPrivateKey given\");\n }\n this.#HDPrivateKey = HD.fromString(HDPrivateKey);\n\n if (token) {\n this.#BAP_TOKEN = token;\n }\n\n if (server) {\n this.#BAP_SERVER = server;\n }\n\n this.getApiData = apiFetcher(this.#BAP_SERVER, this.#BAP_TOKEN);\n }\n\n get lastIdPath(): string {\n return this.#lastIdPath;\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).pubKey.toString();\n }\n\n return this.#HDPrivateKey.pubKey.toString();\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getHdPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).toPublic().toString();\n }\n\n return this.#HDPrivateKey.toPublic().toString();\n }\n\n set BAP_SERVER(bapServer) {\n this.#BAP_SERVER = bapServer;\n for (const key in this.#ids) {\n this.#ids[key].BAP_SERVER = bapServer;\n }\n }\n\n get BAP_SERVER(): string {\n return this.#BAP_SERVER;\n }\n\n set BAP_TOKEN(token) {\n this.#BAP_TOKEN = token;\n for (const key in this.#ids) {\n // @ts-ignore - does not recognize private fields that can be set\n this.#ids[key].BAP_TOKEN = token;\n }\n }\n\n get BAP_TOKEN(): string {\n return this.#BAP_TOKEN;\n }\n\n /**\n * This function verifies that the given bapId matches the given root address\n * This is used as a data integrity check\n *\n * @param bapId MasterID instance\n */\n checkIdBelongs(bapId: MasterID): boolean {\n const derivedChild = this.#HDPrivateKey.derive(bapId.rootPath);\n const checkRootAddress = derivedChild.pubKey.toAddress();\n if (checkRootAddress !== bapId.rootAddress) {\n throw new Error(\"ID does not belong to this private key\");\n }\n\n return true;\n }\n\n /**\n * Returns a list of all the identity keys that are stored in this instance\n *\n * @returns {string[]}\n */\n listIds(): string[] {\n return Object.keys(this.#ids);\n }\n\n /**\n * Create a new Id and link it to this BAP instance\n *\n * This function uses the length of the #ids of this class to determine the next valid path.\n * If not all ids related to this HDPrivateKey have been loaded, determine the path externally\n * and pass it to newId when creating a new ID.\n *\n * @param path\n * @param identityAttributes\n * @param idSeed\n * @returns {*}\n */\n newId(path?: string, identityAttributes: IdentityAttributes = {}, idSeed = \"\"): MasterID {\n let pathToUse: string;\n if (!path) {\n // get next usable path for this key\n pathToUse = this.getNextValidPath();\n } else {\n pathToUse = path;\n }\n\n const newIdentity = new MasterID(\n this.#HDPrivateKey,\n identityAttributes,\n idSeed,\n );\n newIdentity.BAP_SERVER = this.#BAP_SERVER;\n newIdentity.BAP_TOKEN = this.#BAP_TOKEN;\n\n newIdentity.rootPath = pathToUse;\n newIdentity.currentPath = Utils.getNextPath(pathToUse);\n\n const idKey = newIdentity.getIdentityKey();\n this.#ids[idKey] = newIdentity;\n this.#lastIdPath = pathToUse;\n\n return this.#ids[idKey];\n }\n\n /**\n * Remove identity\n *\n * @param idKey\n * @returns {*}\n */\n removeId(idKey: string): void {\n delete this.#ids[idKey];\n }\n\n /**\n * Get the next valid path for the used HDPrivateKey and loaded #ids\n *\n * @returns {string}\n */\n getNextValidPath(): PathPrefix {\n // prefer hardened paths\n if (this.#lastIdPath) {\n return Utils.getNextIdentityPath(this.#lastIdPath);\n }\n\n return `/0'/${Object.keys(this.#ids).length}'/0'`;\n }\n\n /**\n * Get a certain Id\n *\n * @param identityKey\n * @returns {null}\n */\n getId(identityKey: string): MasterID | null {\n return this.#ids[identityKey] || null;\n }\n\n /**\n * This function is used when manipulating ID's, adding or removing attributes etc\n * First create an id through this class and then use getId to get it. Then you can add/edit or\n * increment the signing path and then re-set it with this function.\n *\n * Note: when you getId() from this class, you will be working on the same object as this class\n * has and any changes made will be propagated to the id in this class. When you call exportIds\n * your new changes will also be included, without having to setId().\n *\n * @param bapId\n */\n setId(bapId: MasterID): void {\n this.checkIdBelongs(bapId);\n this.#ids[bapId.getIdentityKey()] = bapId;\n }\n\n /**\n * This function is used to import IDs and attributes from some external storage\n *\n * The ID information should NOT be stored together with the HD private key !\n *\n * @param idData Array of ids that have been exported\n * @param encrypted Whether the data should be treated as being encrypted (default true)\n */\n importIds(idData: Identities | string, encrypted = true): void {\n if (encrypted && typeof idData === \"string\") {\n this.importEncryptedIds(idData);\n return;\n }\n const identity = idData as Identities\n if (!identity.lastIdPath) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n\n if (!identity.ids) {\n throw new Error(`ID data is not in the correct format: ${idData}`);\n }\n\n let lastIdPath = (idData as Identities).lastIdPath;\n for (const id of identity.ids) {\n if (!id.identityKey || !id.identityAttributes || !id.rootAddress) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n const importId = new MasterID(this.#HDPrivateKey, {}, id.idSeed);\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n if (lastIdPath === \"\") {\n lastIdPath = importId.currentPath;\n }\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n }\n\n this.#lastIdPath = lastIdPath;\n }\n\n importEncryptedIds(idData: string): void {\n // decrypt the ids array using ECIES\n const decrypted = this.decrypt(idData);\n const ids = JSON.parse(decrypted) as Identities;\n\n const isOldFormat = Array.isArray(ids)\n if (isOldFormat) {\n console.log(\"Importing old format:\\n\", ids)\n this.importOldIds(ids)\n return\n }\n if (typeof ids !== \"object\") {\n throw new Error(\"decrypted, but found unrecognized identities format\")\n }\n this.importIds(ids, false);\n }\n\n importOldIds(idData: OldIdentity[]): void {\n for (const id of idData) {\n const importId = new MasterID(\n this.#HDPrivateKey,\n {},\n id.idSeed ?? \"\"\n );\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n this.#lastIdPath = importId.currentPath;\n }\n }\n\n\n /**\n * Export identities. If no idKeys are provided, exports all identities.\n * @param idKeys Optional array of identity keys to export. If omitted, exports all identities.\n * @param encrypted Whether to encrypt the export data\n */\n // Overload signatures\n exportIds(idKeys?: string[], encrypted?: true): string;\n exportIds(idKeys: string[] | undefined, encrypted: false): Identities;\n exportIds(idKeys?: string[], encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n const keysToExport = idKeys || Object.keys(this.#ids);\n\n for (const key of keysToExport) {\n if (!this.#ids[key]) {\n throw new Error(`Identity ${key} not found`);\n }\n idData.ids.push(this.#ids[key].export());\n }\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n return idData;\n }\n\n\n /**\n * Export a given ID from this instance for external storage\n *\n * By default this function will encrypt the data, using a derivative child of the main HD key\n *\n * @param idKey The key of the identity to export\n * @param encrypted Whether the data should be encrypted (default true)\n * @returns {[]|*}\n */\n // Overload signatures\n exportId(idKey: string, encrypted?: true): string;\n exportId(idKey: string, encrypted: false): Identities;\n exportId(idKey: string, encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n idData.ids.push(this.#ids[idKey].export());\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n\n return idData\n }\n\n /**\n * Encrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n encrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toBase64(\n // @ts-ignore - you can remove the null when this is merged https://github.com/bitcoin-sv/ts-sdk/pull/123\n electrumEncrypt(toArray(string), derivedChild.pubKey, null),\n );\n }\n\n /**\n * Decrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n decrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toUTF8(\n electrumDecrypt(toArray(string, \"base64\"), derivedChild.privKey),\n );\n }\n\n /**\n * Sign an attestation for a user\n *\n * @param attestationHash The computed attestation hash for the user - this should be calculated with the MasterID class for an identity for the user\n * @param identityKey The identity key we are using for the signing\n * @param counter\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {string[]}\n */\n signAttestationWithAIP(\n attestationHash: string,\n identityKey: string,\n counter = 0,\n dataString = \"\",\n ) {\n const id = this.getId(identityKey);\n if (!id) {\n throw new Error(\"Could not find identity to attest with\");\n }\n\n const attestationBuffer = this.getAttestationBuffer(\n attestationHash,\n counter,\n dataString,\n );\n const { address, signature } = id.signMessage(attestationBuffer);\n\n return this.createAttestationTransaction(\n attestationHash,\n counter,\n address,\n signature,\n dataString,\n );\n }\n\n /**\n * Verify an AIP signed attestation for a user\n *\n * [\n * '0x6a',\n * '0x31424150537561506e66476e53424d33474c56397968785564596534764762644d54',\n * '0x415454455354',\n * '0x33656166366361396334313936356538353831366439336439643034333136393032376633396661623034386333633031333663343364663635376462383761',\n * '0x30',\n * '0x7c',\n * '0x313550636948473232534e4c514a584d6f5355615756693757537163376843667661',\n * '0x424954434f494e5f4543445341',\n * '0x31477531796d52567a595557634638776f6f506a7a4a4c764d383550795a64655876',\n * '0x20ef60c5555001ddb1039bb0f215e46571fcb39ee46f48b089d1c08b0304dbcb3366d8fdf8bafd82be24b5ac42dcd6a5e96c90705dd42e3ad918b1b47ac3ce6ac2'\n * ]\n *\n * @param tx Array of hex values for the OP_RETURN values\n * @returns {{}}\n */\n verifyAttestationWithAIP(tx: string[]): Attestation {\n if (\n !Array.isArray(tx) ||\n tx[0] !== \"0x6a\" ||\n tx[1] !== BAP_BITCOM_ADDRESS_HEX\n ) {\n throw new Error(\"Not a valid BAP transaction\");\n }\n\n const dataOffset = tx[7] === \"0x44415441\" ? 5 : 0; // DATA\n const attestation: Attestation = {\n type: Utils.hexDecode(tx[2]),\n hash: Utils.hexDecode(tx[3]),\n sequence: Utils.hexDecode(tx[4]),\n signingProtocol: Utils.hexDecode(tx[7 + dataOffset]),\n signingAddress: Utils.hexDecode(tx[8 + dataOffset]),\n signature: Utils.hexDecode(tx[9 + dataOffset], \"base64\"),\n };\n\n if (dataOffset && tx[3] === tx[8]) {\n // valid data addition\n attestation.data = Utils.hexDecode(tx[9]);\n }\n\n try {\n const signatureBufferStatements: Buffer[] = [];\n for (let i = 0; i < 6 + dataOffset; i++) {\n signatureBufferStatements.push(\n Buffer.from(tx[i].replace(\"0x\", \"\"), \"hex\"),\n );\n }\n const attestationBuffer = Buffer.concat(signatureBufferStatements as unknown as Uint8Array[]);\n attestation.verified = this.verifySignature(\n attestationBuffer,\n attestation.signingAddress,\n attestation.signature,\n );\n } catch (e) {\n attestation.verified = false;\n }\n\n return attestation;\n }\n\n /**\n * For BAP attestations we use all fields for the attestation\n *\n * @param attestationHash\n * @param counter\n * @param address\n * @param signature\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {[string]}\n */\n createAttestationTransaction(\n attestationHash: string,\n counter: number,\n address: string,\n signature: string,\n dataString = \"\",\n ): string[] {\n const transaction = [\"0x6a\", Utils.hexEncode(BAP_BITCOM_ADDRESS)];\n transaction.push(Utils.hexEncode(\"ATTEST\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(`${counter}`));\n transaction.push(\"0x7c\"); // |\n if (dataString) {\n // data should be a string, either encrypted or stringified JSON if applicable\n transaction.push(Utils.hexEncode(BAP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"DATA\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(dataString));\n transaction.push(\"0x7c\"); // |\n }\n transaction.push(Utils.hexEncode(AIP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"BITCOIN_ECDSA\"));\n transaction.push(Utils.hexEncode(address));\n transaction.push(`0x${Buffer.from(signature, \"base64\").toString(\"hex\")}`);\n\n return transaction;\n }\n\n /**\n * This is a re-creation of how the bitcoinfiles-sdk creates a hash to sign for AIP\n *\n * @param attestationHash\n * @param counter\n * @param dataString Optional data string\n * @returns {Buffer}\n */\n getAttestationBuffer(\n attestationHash: string,\n counter = 0,\n dataString = \"\",\n ): Buffer {\n // re-create how AIP creates the buffer to sign\n let dataStringBuffer = Buffer.from(\"\");\n if (dataString) {\n dataStringBuffer = Buffer.concat([\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"DATA\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(dataString) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n ]);\n }\n return Buffer.concat([\n Buffer.from(\"6a\", \"hex\") as unknown as Uint8Array, // OP_RETURN\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"ATTEST\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(`${counter}`) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n dataStringBuffer as unknown as Uint8Array,\n ]);\n }\n\n /**\n * Verify that the identity challenge is signed by the address\n *\n * @param message Buffer or utf-8 string\n * @param address Bitcoin address of signee\n * @param signature Signature base64 string\n *\n * @return boolean\n */\n verifySignature(\n message: string | Buffer,\n address: string,\n signature: string,\n ): boolean {\n // check the signature against the challenge\n const messageBuffer = Buffer.isBuffer(message)\n ? message\n : Buffer.from(message);\n const sig = Signature.fromCompact(signature, \"base64\");\n let publicKey: PublicKey | undefined;\n const msg = toArray(messageBuffer.toString(\"hex\"), \"hex\");\n for (let recovery = 0; recovery < 4; recovery++) {\n try {\n publicKey = sig.RecoverPublicKey(\n recovery,\n new BigNumber(BSM.magicHash(msg)),\n );\n const sigFitsPubkey = BSM.verify(msg, sig, publicKey);\n if (sigFitsPubkey && publicKey.toAddress() === address) {\n return true;\n }\n } catch (e) {\n // try next recovery\n }\n }\n return false;\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param idKey\n * @param address\n * @param challenge\n * @param signature\n *\n * @returns {Promise<boolean|*>}\n */\n async verifyChallengeSignature(\n idKey: string,\n address: string,\n challenge: string,\n signature: string,\n ): Promise<boolean> {\n // first we test locally before sending to server\n const localVerification = this.verifySignature(challenge, address, signature);\n\n if (!localVerification) {\n return false;\n }\n\n try {\n const response = await this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n idKey,\n address,\n challenge,\n signature,\n });\n\n // Ensure we have a valid response with the expected structure\n if (response?.status === 'success' && response?.result?.valid === true) {\n return true;\n }\n\n return false;\n } catch (error) {\n console.error('API call failed:', error);\n return false;\n }\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param tx\n * @returns {Promise<boolean|*>}\n */\n async isValidAttestationTransaction(tx: string[]): Promise<AttestationValidResponse | false> {\n if (this.verifyAttestationWithAIP(tx)) {\n return this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n tx,\n });\n }\n return false;\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param address\n * @returns {Promise<*>}\n */\n async getIdentityFromAddress(address: string): Promise<GetIdentityByAddressResponse> {\n return this.getApiData<GetIdentityByAddressResponse>(\"/identity/from-address\", {\n address,\n });\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param idKey\n * @returns {Promise<*>}\n */\n async getIdentity(idKey: string): Promise<GetIdentityResponse> {\n return this.getApiData<GetIdentityResponse>(\"/identity/get\", {\n idKey,\n });\n }\n\n /**\n * Get all attestations for the given attestation hash\n *\n * @param attestationHash\n */\n async getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse> {\n // get all BAP ATTEST records for the given attestationHash\n return this.getApiData<GetAttestationResponse>(\"/attestations\", {\n hash: attestationHash,\n });\n }\n\n\n};\n\nexport { MasterID };\nexport type { Attestation, Identity, IdentityAttributes, PathPrefix };\n\n",
5
+ "import { BSM, BigNumber, ECIES, HD, type PublicKey, Signature } from \"@bsv/sdk\";\n\nimport { Utils as BSVUtils } from \"@bsv/sdk\";\nimport { type APIFetcher, apiFetcher } from \"./api\";\nimport type { AttestationValidResponse, GetAttestationResponse, GetIdentityByAddressResponse, GetIdentityResponse } from \"./apiTypes\";\nimport {\n AIP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS_HEX,\n BAP_SERVER,\n ENCRYPTION_PATH,\n} from \"./constants\";\nimport { MasterID } from \"./MasterID\";\nimport type { Attestation, Identity, IdentityAttributes, OldIdentity, PathPrefix } from \"./interface\";\nimport { Utils } from \"./utils\";\nimport { MemberID } from \"./MemberID\";\nconst { toArray, toUTF8, toBase64 } = BSVUtils;\nconst { electrumEncrypt, electrumDecrypt } = ECIES;\n\ntype Identities = { lastIdPath: string; ids: Identity[] };\n\n\n/**\n * BAP class\n *\n * Creates an instance of the BAP class and uses the given HDPrivateKey for all BAP operations.\n *\n * @param HDPrivateKey\n */\nexport class BAP {\n #HDPrivateKey;\n #ids: { [key: string]: MasterID } = {};\n #BAP_SERVER = BAP_SERVER;\n #BAP_TOKEN = \"\";\n #lastIdPath = \"\";\n getApiData: APIFetcher;\n\n constructor(HDPrivateKey: string, token = \"\", server = \"\") {\n if (!HDPrivateKey) {\n throw new Error(\"No HDPrivateKey given\");\n }\n this.#HDPrivateKey = HD.fromString(HDPrivateKey);\n\n if (token) {\n this.#BAP_TOKEN = token;\n }\n\n if (server) {\n this.#BAP_SERVER = server;\n }\n\n this.getApiData = apiFetcher(this.#BAP_SERVER, this.#BAP_TOKEN);\n }\n\n get lastIdPath(): string {\n return this.#lastIdPath;\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).pubKey.toString();\n }\n\n return this.#HDPrivateKey.pubKey.toString();\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getHdPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).toPublic().toString();\n }\n\n return this.#HDPrivateKey.toPublic().toString();\n }\n\n set BAP_SERVER(bapServer) {\n this.#BAP_SERVER = bapServer;\n for (const key in this.#ids) {\n this.#ids[key].BAP_SERVER = bapServer;\n }\n }\n\n get BAP_SERVER(): string {\n return this.#BAP_SERVER;\n }\n\n set BAP_TOKEN(token) {\n this.#BAP_TOKEN = token;\n for (const key in this.#ids) {\n // @ts-ignore - does not recognize private fields that can be set\n this.#ids[key].BAP_TOKEN = token;\n }\n }\n\n get BAP_TOKEN(): string {\n return this.#BAP_TOKEN;\n }\n\n /**\n * This function verifies that the given bapId matches the given root address\n * This is used as a data integrity check\n *\n * @param bapId MasterID instance\n */\n checkIdBelongs(bapId: MasterID): boolean {\n const derivedChild = this.#HDPrivateKey.derive(bapId.rootPath);\n const checkRootAddress = derivedChild.pubKey.toAddress();\n if (checkRootAddress !== bapId.rootAddress) {\n throw new Error(\"ID does not belong to this private key\");\n }\n\n return true;\n }\n\n /**\n * Returns a list of all the identity keys that are stored in this instance\n *\n * @returns {string[]}\n */\n listIds(): string[] {\n return Object.keys(this.#ids);\n }\n\n /**\n * Create a new Id and link it to this BAP instance\n *\n * This function uses the length of the #ids of this class to determine the next valid path.\n * If not all ids related to this HDPrivateKey have been loaded, determine the path externally\n * and pass it to newId when creating a new ID.\n *\n * @param path\n * @param identityAttributes\n * @param idSeed\n * @returns {*}\n */\n newId(path?: string, identityAttributes: IdentityAttributes = {}, idSeed = \"\"): MasterID {\n let pathToUse: string;\n if (!path) {\n // get next usable path for this key\n pathToUse = this.getNextValidPath();\n } else {\n pathToUse = path;\n }\n\n const newIdentity = new MasterID(\n this.#HDPrivateKey,\n identityAttributes,\n idSeed,\n );\n newIdentity.BAP_SERVER = this.#BAP_SERVER;\n newIdentity.BAP_TOKEN = this.#BAP_TOKEN;\n\n newIdentity.rootPath = pathToUse;\n newIdentity.currentPath = Utils.getNextPath(pathToUse);\n\n const idKey = newIdentity.getIdentityKey();\n this.#ids[idKey] = newIdentity;\n this.#lastIdPath = pathToUse;\n\n return this.#ids[idKey];\n }\n\n /**\n * Remove identity\n *\n * @param idKey\n * @returns {*}\n */\n removeId(idKey: string): void {\n delete this.#ids[idKey];\n }\n\n /**\n * Get the next valid path for the used HDPrivateKey and loaded #ids\n *\n * @returns {string}\n */\n getNextValidPath(): PathPrefix {\n // prefer hardened paths\n if (this.#lastIdPath) {\n return Utils.getNextIdentityPath(this.#lastIdPath);\n }\n\n return `/0'/${Object.keys(this.#ids).length}'/0'`;\n }\n\n /**\n * Get a certain Id\n *\n * @param identityKey\n * @returns {null}\n */\n getId(identityKey: string): MasterID | null {\n return this.#ids[identityKey] || null;\n }\n\n /**\n * This function is used when manipulating ID's, adding or removing attributes etc\n * First create an id through this class and then use getId to get it. Then you can add/edit or\n * increment the signing path and then re-set it with this function.\n *\n * Note: when you getId() from this class, you will be working on the same object as this class\n * has and any changes made will be propagated to the id in this class. When you call exportIds\n * your new changes will also be included, without having to setId().\n *\n * @param bapId\n */\n setId(bapId: MasterID): void {\n this.checkIdBelongs(bapId);\n this.#ids[bapId.getIdentityKey()] = bapId;\n }\n\n /**\n * This function is used to import IDs and attributes from some external storage\n *\n * The ID information should NOT be stored together with the HD private key !\n *\n * @param idData Array of ids that have been exported\n * @param encrypted Whether the data should be treated as being encrypted (default true)\n */\n importIds(idData: Identities | string, encrypted = true): void {\n if (encrypted && typeof idData === \"string\") {\n this.importEncryptedIds(idData);\n return;\n }\n const identity = idData as Identities\n if (!identity.lastIdPath) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n\n if (!identity.ids) {\n throw new Error(`ID data is not in the correct format: ${idData}`);\n }\n\n let lastIdPath = (idData as Identities).lastIdPath;\n for (const id of identity.ids) {\n if (!id.identityKey || !id.identityAttributes || !id.rootAddress) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n const importId = new MasterID(this.#HDPrivateKey, {}, id.idSeed);\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n if (lastIdPath === \"\") {\n lastIdPath = importId.currentPath;\n }\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n }\n\n this.#lastIdPath = lastIdPath;\n }\n\n importEncryptedIds(idData: string): void {\n // decrypt the ids array using ECIES\n const decrypted = this.decrypt(idData);\n const ids = JSON.parse(decrypted) as Identities;\n\n const isOldFormat = Array.isArray(ids)\n if (isOldFormat) {\n console.log(\"Importing old format:\\n\", ids)\n this.importOldIds(ids)\n return\n }\n if (typeof ids !== \"object\") {\n throw new Error(\"decrypted, but found unrecognized identities format\")\n }\n this.importIds(ids, false);\n }\n\n importOldIds(idData: OldIdentity[]): void {\n for (const id of idData) {\n const importId = new MasterID(\n this.#HDPrivateKey,\n {},\n id.idSeed ?? \"\"\n );\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n this.#lastIdPath = importId.currentPath;\n }\n }\n\n\n /**\n * Export identities. If no idKeys are provided, exports all identities.\n * @param idKeys Optional array of identity keys to export. If omitted, exports all identities.\n * @param encrypted Whether to encrypt the export data\n */\n // Overload signatures\n exportIds(idKeys?: string[], encrypted?: true): string;\n exportIds(idKeys: string[] | undefined, encrypted: false): Identities;\n exportIds(idKeys?: string[], encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n const keysToExport = idKeys || Object.keys(this.#ids);\n\n for (const key of keysToExport) {\n if (!this.#ids[key]) {\n throw new Error(`Identity ${key} not found`);\n }\n idData.ids.push(this.#ids[key].export());\n }\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n return idData;\n }\n\n\n /**\n * Export a given ID from this instance for external storage\n *\n * By default this function will encrypt the data, using a derivative child of the main HD key\n *\n * @param idKey The key of the identity to export\n * @param encrypted Whether the data should be encrypted (default true)\n * @returns {[]|*}\n */\n // Overload signatures\n exportId(idKey: string, encrypted?: true): string;\n exportId(idKey: string, encrypted: false): Identities;\n exportId(idKey: string, encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n idData.ids.push(this.#ids[idKey].export());\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n\n return idData\n }\n\n /**\n * Encrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n encrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toBase64(\n // @ts-ignore - you can remove the null when this is merged https://github.com/bitcoin-sv/ts-sdk/pull/123\n electrumEncrypt(toArray(string), derivedChild.pubKey, null),\n );\n }\n\n /**\n * Decrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n decrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toUTF8(\n electrumDecrypt(toArray(string, \"base64\"), derivedChild.privKey),\n );\n }\n\n /**\n * Sign an attestation for a user\n *\n * @param attestationHash The computed attestation hash for the user - this should be calculated with the MasterID class for an identity for the user\n * @param identityKey The identity key we are using for the signing\n * @param counter\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {string[]}\n */\n signAttestationWithAIP(\n attestationHash: string,\n identityKey: string,\n counter = 0,\n dataString = \"\",\n ) {\n const id = this.getId(identityKey);\n if (!id) {\n throw new Error(\"Could not find identity to attest with\");\n }\n\n const attestationBuffer = this.getAttestationBuffer(\n attestationHash,\n counter,\n dataString,\n );\n const { address, signature } = id.signMessage(attestationBuffer);\n\n return this.createAttestationTransaction(\n attestationHash,\n counter,\n address,\n signature,\n dataString,\n );\n }\n\n /**\n * Verify an AIP signed attestation for a user\n *\n * [\n * '0x6a',\n * '0x31424150537561506e66476e53424d33474c56397968785564596534764762644d54',\n * '0x415454455354',\n * '0x33656166366361396334313936356538353831366439336439643034333136393032376633396661623034386333633031333663343364663635376462383761',\n * '0x30',\n * '0x7c',\n * '0x313550636948473232534e4c514a584d6f5355615756693757537163376843667661',\n * '0x424954434f494e5f4543445341',\n * '0x31477531796d52567a595557634638776f6f506a7a4a4c764d383550795a64655876',\n * '0x20ef60c5555001ddb1039bb0f215e46571fcb39ee46f48b089d1c08b0304dbcb3366d8fdf8bafd82be24b5ac42dcd6a5e96c90705dd42e3ad918b1b47ac3ce6ac2'\n * ]\n *\n * @param tx Array of hex values for the OP_RETURN values\n * @returns {{}}\n */\n verifyAttestationWithAIP(tx: string[]): Attestation {\n if (\n !Array.isArray(tx) ||\n tx[0] !== \"0x6a\" ||\n tx[1] !== BAP_BITCOM_ADDRESS_HEX\n ) {\n throw new Error(\"Not a valid BAP transaction\");\n }\n\n const dataOffset = tx[7] === \"0x44415441\" ? 5 : 0; // DATA\n const attestation: Attestation = {\n type: Utils.hexDecode(tx[2]),\n hash: Utils.hexDecode(tx[3]),\n sequence: Utils.hexDecode(tx[4]),\n signingProtocol: Utils.hexDecode(tx[7 + dataOffset]),\n signingAddress: Utils.hexDecode(tx[8 + dataOffset]),\n signature: Utils.hexDecode(tx[9 + dataOffset], \"base64\"),\n };\n\n if (dataOffset && tx[3] === tx[8]) {\n // valid data addition\n attestation.data = Utils.hexDecode(tx[9]);\n }\n\n try {\n const signatureBufferStatements: Buffer[] = [];\n for (let i = 0; i < 6 + dataOffset; i++) {\n signatureBufferStatements.push(\n Buffer.from(tx[i].replace(\"0x\", \"\"), \"hex\"),\n );\n }\n const attestationBuffer = Buffer.concat(signatureBufferStatements as unknown as Uint8Array[]);\n attestation.verified = this.verifySignature(\n attestationBuffer,\n attestation.signingAddress,\n attestation.signature,\n );\n } catch (e) {\n attestation.verified = false;\n }\n\n return attestation;\n }\n\n /**\n * For BAP attestations we use all fields for the attestation\n *\n * @param attestationHash\n * @param counter\n * @param address\n * @param signature\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {[string]}\n */\n createAttestationTransaction(\n attestationHash: string,\n counter: number,\n address: string,\n signature: string,\n dataString = \"\",\n ): string[] {\n const transaction = [\"0x6a\", Utils.hexEncode(BAP_BITCOM_ADDRESS)];\n transaction.push(Utils.hexEncode(\"ATTEST\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(`${counter}`));\n transaction.push(\"0x7c\"); // |\n if (dataString) {\n // data should be a string, either encrypted or stringified JSON if applicable\n transaction.push(Utils.hexEncode(BAP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"DATA\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(dataString));\n transaction.push(\"0x7c\"); // |\n }\n transaction.push(Utils.hexEncode(AIP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"BITCOIN_ECDSA\"));\n transaction.push(Utils.hexEncode(address));\n transaction.push(`0x${Buffer.from(signature, \"base64\").toString(\"hex\")}`);\n\n return transaction;\n }\n\n /**\n * This is a re-creation of how the bitcoinfiles-sdk creates a hash to sign for AIP\n *\n * @param attestationHash\n * @param counter\n * @param dataString Optional data string\n * @returns {Buffer}\n */\n getAttestationBuffer(\n attestationHash: string,\n counter = 0,\n dataString = \"\",\n ): Buffer {\n // re-create how AIP creates the buffer to sign\n let dataStringBuffer = Buffer.from(\"\");\n if (dataString) {\n dataStringBuffer = Buffer.concat([\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"DATA\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(dataString) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n ]);\n }\n return Buffer.concat([\n Buffer.from(\"6a\", \"hex\") as unknown as Uint8Array, // OP_RETURN\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"ATTEST\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(`${counter}`) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n dataStringBuffer as unknown as Uint8Array,\n ]);\n }\n\n /**\n * Verify that the identity challenge is signed by the address\n *\n * @param message Buffer or utf-8 string\n * @param address Bitcoin address of signee\n * @param signature Signature base64 string\n *\n * @return boolean\n */\n verifySignature(\n message: string | Buffer,\n address: string,\n signature: string,\n ): boolean {\n // check the signature against the challenge\n const messageBuffer = Buffer.isBuffer(message)\n ? message\n : Buffer.from(message);\n const sig = Signature.fromCompact(signature, \"base64\");\n let publicKey: PublicKey | undefined;\n const msg = toArray(messageBuffer.toString(\"hex\"), \"hex\");\n for (let recovery = 0; recovery < 4; recovery++) {\n try {\n publicKey = sig.RecoverPublicKey(\n recovery,\n new BigNumber(BSM.magicHash(msg)),\n );\n const sigFitsPubkey = BSM.verify(msg, sig, publicKey);\n if (sigFitsPubkey && publicKey.toAddress() === address) {\n return true;\n }\n } catch (e) {\n // try next recovery\n }\n }\n return false;\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param idKey\n * @param address\n * @param challenge\n * @param signature\n *\n * @returns {Promise<boolean|*>}\n */\n async verifyChallengeSignature(\n idKey: string,\n address: string,\n challenge: string,\n signature: string,\n ): Promise<boolean> {\n // first we test locally before sending to server\n const localVerification = this.verifySignature(challenge, address, signature);\n\n if (!localVerification) {\n return false;\n }\n\n try {\n const response = await this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n idKey,\n address,\n challenge,\n signature,\n });\n\n // Ensure we have a valid response with the expected structure\n if (response?.status === 'success' && response?.result?.valid === true) {\n return true;\n }\n\n return false;\n } catch (error) {\n console.error('API call failed:', error);\n return false;\n }\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param tx\n * @returns {Promise<boolean|*>}\n */\n async isValidAttestationTransaction(tx: string[]): Promise<AttestationValidResponse | false> {\n if (this.verifyAttestationWithAIP(tx)) {\n return this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n tx,\n });\n }\n return false;\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param address\n * @returns {Promise<*>}\n */\n async getIdentityFromAddress(address: string): Promise<GetIdentityByAddressResponse> {\n return this.getApiData<GetIdentityByAddressResponse>(\"/identity/from-address\", {\n address,\n });\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param idKey\n * @returns {Promise<*>}\n */\n async getIdentity(idKey: string): Promise<GetIdentityResponse> {\n return this.getApiData<GetIdentityResponse>(\"/identity/get\", {\n idKey,\n });\n }\n\n /**\n * Get all attestations for the given attestation hash\n *\n * @param attestationHash\n */\n async getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse> {\n // get all BAP ATTEST records for the given attestationHash\n return this.getApiData<GetAttestationResponse>(\"/attestations\", {\n hash: attestationHash,\n });\n }\n\n\n};\n\nexport { MasterID, MemberID };\nexport type { Attestation, Identity, IdentityAttributes, PathPrefix };\n\n",
6
6
  "\n/**\n\t * Helper function to get attestation from a BAP API server\n\t *\n\t * @param apiUrl\n\t * @param apiData\n\t * @returns {Promise<any>}\n\t */\nexport const getApiData = async <T>(apiUrl: string, apiData: unknown, server: string, token: string): Promise<T> => {\n const url = `${server}${apiUrl}`;\n const response = await fetch(url, {\n method: \"post\",\n headers: {\n \"Content-type\": \"application/json; charset=utf-8\",\n token,\n format: \"json\",\n },\n body: JSON.stringify(apiData),\n });\n\n return response.json();\n}\n\nexport type APIFetcher = <T>(url: string, data: unknown) => Promise<T>;\n\nexport const apiFetcher = (host: string, token: string): APIFetcher => async <T>(url: string, data: unknown): Promise<T> => {\n return getApiData<T>(url, data, host, token);\n}",
7
7
  "export const BAP_BITCOM_ADDRESS = '1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT';\nexport const BAP_BITCOM_ADDRESS_HEX = `0x${Buffer.from(BAP_BITCOM_ADDRESS).toString('hex')}`;\nexport const AIP_BITCOM_ADDRESS = '15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva';\nexport const AIP_BITCOM_ADDRESS_HEX = `0x${Buffer.from(AIP_BITCOM_ADDRESS).toString('hex')}`;\nexport const BAP_SERVER = 'https://api.sigmaidentity.com/v1';\nexport const MAX_INT = 2147483648 - 1; // 0x80000000\n\n// This is just a choice for this library and could be anything else if so needed/wanted\n// but it is advisable to use the same derivation between libraries for compatibility\nexport const SIGNING_PATH_PREFIX = 'm/424150\\'/0\\'/0\\''; // BAP in hex\nexport const ENCRYPTION_PATH = `m/424150'/${MAX_INT}'/${MAX_INT}'`;\n",
8
8
  "import { BSM, Utils as BSVUtils, BigNumber, ECIES, type HD, Hash, PublicKey, type Signature } from \"@bsv/sdk\";\n\nimport { type APIFetcher, apiFetcher } from \"./api\";\nimport type { GetAttestationResponse, GetSigningKeysResponse } from \"./apiTypes\";\nimport {\n AIP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS,\n BAP_SERVER,\n ENCRYPTION_PATH,\n MAX_INT,\n SIGNING_PATH_PREFIX,\n} from \"./constants\";\nimport type {\n Identity,\n IdentityAttribute,\n IdentityAttributes,\n OldIdentity,\n} from \"./interface\";\nimport { Utils } from \"./utils\";\nimport { MemberID, type MemberIdentity } from './MemberID';\nconst { toArray, toHex, toBase58, toUTF8, toBase64 } = BSVUtils;\nconst { electrumDecrypt, electrumEncrypt } = ECIES;\nconst { magicHash } = BSM;\n/**\n * MasterID class\n *\n * This class should be used in conjunction with the BAP class\n *\n * @type {MasterID}\n */\nclass MasterID {\n #HDPrivateKey: HD;\n #BAP_SERVER: string = BAP_SERVER;\n #BAP_TOKEN = \"\";\n #rootPath: string;\n #previousPath: string;\n #currentPath: string;\n #idSeed: string;\n\n idName: string;\n description: string;\n\n rootAddress: string;\n identityKey: string;\n identityAttributes: IdentityAttributes;\n\n getApiData: APIFetcher\n\n constructor(\n HDPrivateKey: HD,\n identityAttributes: IdentityAttributes = {},\n idSeed = \"\",\n ) {\n this.#idSeed = idSeed;\n if (idSeed) {\n // create a new HDPrivateKey based on the seed\n const seedHex = toHex(Hash.sha256(idSeed, \"utf8\"));\n const seedPath = Utils.getSigningPathFromHex(seedHex);\n this.#HDPrivateKey = HDPrivateKey.derive(seedPath);\n } else {\n this.#HDPrivateKey = HDPrivateKey;\n }\n\n this.idName = \"ID 1\";\n this.description = \"\";\n\n this.#rootPath = `${SIGNING_PATH_PREFIX}/0/0/0`;\n this.#previousPath = `${SIGNING_PATH_PREFIX}/0/0/0`;\n this.#currentPath = `${SIGNING_PATH_PREFIX}/0/0/1`;\n\n const rootChild = this.#HDPrivateKey.derive(this.#rootPath);\n this.rootAddress = rootChild.privKey.toPublicKey().toAddress();\n this.identityKey = this.deriveIdentityKey(this.rootAddress);\n\n // unlink the object\n const attributes = { ...identityAttributes };\n this.identityAttributes = this.parseAttributes(attributes);\n\n this.getApiData = apiFetcher(this.#BAP_SERVER, this.#BAP_TOKEN);\n }\n\n set BAP_SERVER(bapServer) {\n this.#BAP_SERVER = bapServer;\n }\n\n get BAP_SERVER(): string {\n return this.#BAP_SERVER;\n }\n\n set BAP_TOKEN(token) {\n this.#BAP_TOKEN = token;\n }\n\n get BAP_TOKEN(): string {\n return this.#BAP_TOKEN;\n }\n\n deriveIdentityKey(address: string): string {\n // base58( ripemd160 ( sha256 ( rootAddress ) ) )\n const rootAddressHash = toHex(Hash.sha256(address, \"utf8\"));\n return toBase58(Hash.ripemd160(rootAddressHash, \"hex\"));\n }\n\n /**\n * Helper function to parse identity attributes\n *\n * @param identityAttributes\n * @returns {{}}\n */\n parseAttributes(\n identityAttributes: IdentityAttributes | string,\n ): IdentityAttributes {\n if (typeof identityAttributes === \"string\") {\n return this.parseStringUrns(identityAttributes);\n }\n\n for (const key in identityAttributes) {\n if (!identityAttributes[key].value || !identityAttributes[key].nonce) {\n throw new Error(\"Invalid identity attribute\");\n }\n }\n\n return identityAttributes || {};\n }\n\n /**\n * Parse a text of urn string into identity attributes\n *\n * urn:bap:id:name:John Doe:e2c6fb4063cc04af58935737eaffc938011dff546d47b7fbb18ed346f8c4d4fa\n * urn:bap:id:birthday:1990-05-22:e61f23cbbb2284842d77965e2b0e32f0ca890b1894ca4ce652831347ee3596d9\n * urn:bap:id:over18:1:480ca17ccaacd671b28dc811332525f2f2cd594d8e8e7825de515ce5d52d30e8\n *\n * @param urnIdentityAttributes\n */\n parseStringUrns(urnIdentityAttributes: string): IdentityAttributes {\n const identityAttributes: IdentityAttributes = {};\n // avoid forEach\n\n const attributesRaw = urnIdentityAttributes\n .replace(/^\\s+/g, \"\")\n .replace(/\\r/gm, \"\")\n .split(\"\\n\");\n\n for (const line of attributesRaw) {\n // remove any whitespace from the string (trim)\n const attribute = line.replace(/^\\s+/g, \"\").replace(/\\s+$/g, \"\");\n const urn = attribute.split(\":\");\n if (\n urn[0] === \"urn\" &&\n urn[1] === \"bap\" &&\n urn[2] === \"id\" &&\n urn[3] &&\n urn[4] &&\n urn[5]\n ) {\n identityAttributes[urn[3]] = {\n value: urn[4],\n nonce: urn[5],\n };\n }\n }\n\n return identityAttributes;\n }\n\n /**\n * Returns the identity key\n *\n * @returns {*|string}\n */\n getIdentityKey(): string {\n return this.identityKey;\n }\n\n /**\n * Returns all the attributes in the identity\n *\n * @returns {*}\n */\n getAttributes(): IdentityAttributes {\n return this.identityAttributes;\n }\n\n /**\n * Get the value of the given attribute\n *\n * @param attributeName\n * @returns {{}|null}\n */\n getAttribute(attributeName: string): IdentityAttribute | null {\n if (this.identityAttributes[attributeName]) {\n return this.identityAttributes[attributeName];\n }\n\n return null;\n }\n\n /**\n * Set the value of the given attribute\n *\n * If an empty value ('' || null || false) is given, the attribute is removed from the ID\n *\n * @param attributeName string\n * @param attributeValue any\n * @returns {{}|null}\n */\n setAttribute(attributeName: string, attributeValue: string | Record<string, string>): void {\n if (!attributeValue) {\n return;\n }\n\n if (this.identityAttributes[attributeName]) {\n this.updateExistingAttribute(attributeName, attributeValue);\n } else {\n this.createNewAttribute(attributeName, attributeValue);\n }\n }\n\n private updateExistingAttribute(\n attributeName: string,\n attributeValue: string | Record<string, string>\n ): void {\n if (typeof attributeValue === 'string') {\n this.identityAttributes[attributeName].value = attributeValue;\n return;\n }\n\n this.identityAttributes[attributeName].value = attributeValue.value || '';\n if (attributeValue.nonce) {\n this.identityAttributes[attributeName].nonce = attributeValue.nonce;\n }\n }\n\n private createNewAttribute(\n attributeName: string,\n attributeValue: string | Record<string, string>\n ): void {\n if (typeof attributeValue === 'string') {\n this.addAttribute(attributeName, attributeValue);\n return;\n }\n\n this.addAttribute(\n attributeName,\n attributeValue.value || '',\n attributeValue.nonce\n );\n }\n\n /**\n * Unset the given attribute from the ID\n *\n * @param attributeName\n * @returns {{}|null}\n */\n unsetAttribute(attributeName: string): void {\n delete this.identityAttributes[attributeName];\n }\n\n /**\n * Get all attribute urn's for this id\n *\n * @returns {string}\n */\n getAttributeUrns(): string {\n let urns = \"\";\n for (const key in this.identityAttributes) {\n const urn = this.getAttributeUrn(key);\n if (urn) {\n urns += `${urn}\\n`;\n }\n }\n\n return urns;\n }\n\n /**\n * Create an return the attribute urn for the given attribute\n *\n * @param attributeName\n * @returns {string|null}\n */\n getAttributeUrn(attributeName: string): string | null {\n const attribute = this.identityAttributes[attributeName];\n if (attribute) {\n return `urn:bap:id:${attributeName}:${attribute.value}:${attribute.nonce}`;\n }\n\n return null;\n }\n\n /**\n * Add an attribute to this identity\n *\n * @param attributeName\n * @param value\n * @param nonce\n */\n addAttribute(attributeName: string, value: string, nonce = \"\"): void {\n let nonceToUse = nonce;\n if (!nonce) {\n nonceToUse = Utils.getRandomString();\n }\n\n this.identityAttributes[attributeName] = {\n value,\n nonce: nonceToUse,\n };\n }\n\n /**\n * This should be called with the last part of the signing path (/.../.../...)\n * This library assumes the first part is m/424150'/0'/0' as defined at the top of this file\n *\n * @param path The second path of the signing path in the format [0-9]{0,9}/[0-9]{0,9}/[0-9]{0,9}\n */\n set rootPath(path: string) {\n if (this.#HDPrivateKey) {\n let pathToUse = path;\n if (path.split(\"/\").length < 5) {\n pathToUse = `${SIGNING_PATH_PREFIX}${path}`;\n }\n\n if (!this.validatePath(pathToUse)) {\n throw new Error(`invalid signing path given ${pathToUse}`);\n }\n\n this.#rootPath = pathToUse;\n\n const derivedChild = this.#HDPrivateKey.derive(pathToUse);\n this.rootAddress = derivedChild.pubKey.toAddress();\n // Identity keys should be derivatives of the root address - this allows checking\n // of the creation transaction\n this.identityKey = this.deriveIdentityKey(this.rootAddress);\n\n // we also set this previousPath / currentPath to the root as we seem to be (re)setting this ID\n this.#previousPath = pathToUse;\n this.#currentPath = pathToUse;\n }\n }\n\n get rootPath(): string {\n return this.#rootPath;\n }\n\n getRootPath(): string {\n return this.#rootPath;\n }\n\n /**\n * This should be called with the last part of the signing path (/.../.../...)\n * This library assumes the first part is m/424150'/0'/0' as defined at the top of this file\n *\n * @param path The second path of the signing path in the format [0-9]{0,9}/[0-9]{0,9}/[0-9]{0,9}\n */\n set currentPath(path) {\n let pathToUse = path;\n if (path.split(\"/\").length < 5) {\n pathToUse = `${SIGNING_PATH_PREFIX}${path}`;\n }\n\n if (!this.validatePath(pathToUse)) {\n throw new Error(\"invalid signing path given\");\n }\n\n this.#previousPath = this.#currentPath;\n this.#currentPath = pathToUse;\n }\n\n get currentPath(): string {\n return this.#currentPath;\n }\n\n get previousPath(): string {\n return this.#previousPath;\n }\n\n /**\n * This can be used to break the deterministic way child keys are created to make it harder for\n * an attacker to steal the identites when the root key is compromised. This does however require\n * the seeds to be stored at all times. If the seed is lost, the identity will not be recoverable.\n */\n get idSeed(): string {\n return this.#idSeed;\n }\n\n /**\n * Increment current path to a new path\n *\n * @returns {*}\n */\n incrementPath(): void {\n this.currentPath = Utils.getNextPath(this.currentPath);\n }\n\n /**\n * Check whether the given path is a valid path for use with this class\n * The signing paths used here always have a length of 3\n *\n * @param path The last part of the signing path (example \"/0/0/1\")\n * @returns {boolean}\n */\n validatePath(path: string) {\n /* eslint-disable max-len */\n if (\n path.match(\n /\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?/,\n )\n ) {\n const pathValues = path.split(\"/\");\n if (\n pathValues.length === 7 &&\n Number(pathValues[1].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[2].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[3].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[4].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[5].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[6].replace(\"'\", \"\")) <= MAX_INT\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get the OP_RETURN for the initial ID transaction (signed with root address)\n *\n * @returns {[]}\n */\n getInitialIdTransaction() {\n return this.getIdTransaction(this.#rootPath);\n }\n\n /**\n * Get the OP_RETURN for the ID transaction of the current address / path\n *\n * @returns {[]}\n */\n getIdTransaction(previousPath = \"\") {\n if (this.#currentPath === this.#rootPath) {\n throw new Error(\n \"Current path equals rootPath. ID was probably not initialized properly\",\n );\n }\n\n const opReturn = [\n Buffer.from(BAP_BITCOM_ADDRESS).toString(\"hex\"),\n Buffer.from(\"ID\").toString(\"hex\"),\n Buffer.from(this.identityKey).toString(\"hex\"),\n Buffer.from(this.getCurrentAddress()).toString(\"hex\"),\n ];\n\n return this.signOpReturnWithAIP(\n opReturn,\n previousPath || this.#previousPath,\n );\n }\n\n /**\n * Get address for given path\n *\n * @param path\n * @returns {*}\n */\n getAddress(path: string): string {\n const derivedChild = this.#HDPrivateKey.derive(path);\n return derivedChild.privKey.toPublicKey().toAddress();\n }\n\n /**\n * Get current signing address\n *\n * @returns {*}\n */\n getCurrentAddress(): string {\n return this.getAddress(this.#currentPath);\n }\n\n /**\n * Get the public key for encrypting data for this identity\n */\n getEncryptionPublicKey(): string {\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const encryptionKey = HDPrivateKey.derive(ENCRYPTION_PATH).privKey;\n // @ts-ignore\n return encryptionKey.toPublicKey().toString();\n }\n\n /**\n * Get the public key for encrypting data for this identity, using a seed for the encryption\n */\n getEncryptionPublicKeyWithSeed(seed: string): string {\n const encryptionKey = this.getEncryptionPrivateKeyWithSeed(seed);\n // @ts-ignore\n return encryptionKey.toPublicKey().toString(\"hex\");\n }\n\n /**\n * Encrypt the given string data with the identity encryption key\n * @param stringData\n * @param counterPartyPublicKey Optional public key of the counterparty\n * @return string Base64\n */\n encrypt(stringData: string, counterPartyPublicKey?: string): string {\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const encryptionKey = HDPrivateKey.derive(ENCRYPTION_PATH).privKey;\n const publicKey = encryptionKey.toPublicKey();\n const pubKey = counterPartyPublicKey\n ? PublicKey.fromString(counterPartyPublicKey)\n : publicKey;\n // @ts-ignore - remove this when SDK is updated\n return toBase64(electrumEncrypt(toArray(stringData), pubKey, null));\n }\n\n /**\n * Decrypt the given ciphertext with the identity encryption key\n * @param ciphertext\n */\n decrypt(ciphertext: string, counterPartyPublicKey?: string): string {\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const encryptionKey = HDPrivateKey.derive(ENCRYPTION_PATH).privKey;\n let pubKey = undefined\n if (counterPartyPublicKey) {\n pubKey = PublicKey.fromString(counterPartyPublicKey);\n }\n return toUTF8(electrumDecrypt(toArray(ciphertext, \"base64\"), encryptionKey, pubKey));\n }\n\n /**\n * Encrypt the given string data with the identity encryption key\n * @param stringData\n * @param seed String seed\n * @param counterPartyPublicKey Optional public key of the counterparty\n * @return string Base64\n */\n encryptWithSeed(\n stringData: string,\n seed: string,\n counterPartyPublicKey?: string,\n ): string {\n const encryptionKey = this.getEncryptionPrivateKeyWithSeed(seed);\n const publicKey = encryptionKey.toPublicKey();\n const pubKey = counterPartyPublicKey\n ? PublicKey.fromString(counterPartyPublicKey)\n : publicKey;\n return toBase64(electrumEncrypt(toArray(stringData), pubKey, encryptionKey));\n }\n\n /**\n * Decrypt the given ciphertext with the identity encryption key\n * @param ciphertext\n * @param seed String seed\n // * @param counterPartyPublicKey Public key of the counterparty\n */\n decryptWithSeed(ciphertext: string, seed: string, counterPartyPublicKey?: string): string {\n const encryptionKey = this.getEncryptionPrivateKeyWithSeed(seed);\n let pubKey = undefined\n if (counterPartyPublicKey) {\n pubKey = PublicKey.fromString(counterPartyPublicKey);\n }\n return toUTF8(electrumDecrypt(toArray(ciphertext, \"base64\"), encryptionKey, pubKey));\n }\n\n private getEncryptionPrivateKeyWithSeed(seed: string) {\n const pathHex = toHex(Hash.sha256(seed, \"utf8\"));\n const path = Utils.getSigningPathFromHex(pathHex);\n\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n return HDPrivateKey.derive(path).privKey;\n }\n\n /**\n * Get an attestation string for the given urn for this identity\n *\n * @param urn\n * @returns {string}\n */\n getAttestation(urn: string) {\n const urnHash = Hash.sha256(urn, \"utf8\");\n return `bap:attest:${toHex(urnHash)}:${this.getIdentityKey()}`;\n }\n\n /**\n * Generate and return the attestation hash for the given attribute of this identity\n *\n * @param attribute Attribute name (name, email etc.)\n * @returns {string}\n */\n getAttestationHash(attribute: string) {\n const urn = this.getAttributeUrn(attribute);\n if (!urn) return null;\n\n const attestation = this.getAttestation(urn);\n const attestationHash = Hash.sha256(attestation, \"utf8\");\n\n return toHex(attestationHash);\n }\n\n /**\n * Sign a message with the current signing address of this identity\n *\n * @param message\n * @param signingPath\n * @returns {{address: string, signature: string}}\n */\n signMessage(message: string | Buffer, signingPath = \"\"): { address: string, signature: string } {\n let msg: Buffer;\n if (!(message instanceof Buffer)) {\n msg = Buffer.from(message);\n } else {\n msg = message;\n }\n\n const pathToUse = signingPath || this.#currentPath;\n const childPk = this.#HDPrivateKey.derive(pathToUse).privKey;\n const address = childPk.toAddress();\n\n // Needed to calculate the recovery factor\n const dummySig = BSM.sign(toArray(message), childPk, 'raw') as Signature;\n const h = new BigNumber(magicHash(toArray(message, \"utf8\")));\n const r = dummySig.CalculateRecoveryFactor(\n childPk.toPublicKey(),\n h,\n );\n const signature = (BSM.sign(toArray(msg), childPk, 'raw') as Signature).toCompact(\n r,\n true,\n \"base64\",\n ) as string;\n\n return { address, signature };\n }\n\n /**\n * Sign a message using a key based on the given string seed\n *\n * This works by creating a private key from the root key of this identity. It will always\n * work with the rootPath / rootKey, to be deterministic. It will not change even if the keys\n * are rotated for this ID.\n *\n * This is used in for instance deterministic login systems, that do not support BAP.\n *\n * @param message\n * @param seed {string} String seed that will be used to generate a path\n */\n signMessageWithSeed(\n message: string,\n seed: string,\n ): { address: string; signature: string } {\n const pathHex = toHex(Hash.sha256(seed, \"utf8\"));\n const path = Utils.getSigningPathFromHex(pathHex);\n\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const derivedChild = HDPrivateKey.derive(path);\n const address = derivedChild.privKey.toPublicKey().toAddress();\n\n const dummySig = BSM.sign(toArray(message), derivedChild.privKey, 'raw') as Signature;\n\n const h = new BigNumber(magicHash(toArray(message, \"utf8\")));\n const r = dummySig.CalculateRecoveryFactor(\n derivedChild.privKey.toPublicKey(),\n h,\n );\n\n const signature = (BSM.sign(\n toArray(Buffer.from(message)),\n derivedChild.privKey,\n 'raw',\n ) as Signature).toCompact(r, true, \"base64\") as string;\n\n return { address, signature };\n }\n\n /**\n * Sign an op_return hex array with AIP\n * @param opReturn {array}\n * @param signingPath {string}\n * @param outputType {string}\n * @return {[]}\n */\n signOpReturnWithAIP(\n opReturn: string[],\n signingPath = \"\",\n outputType: BufferEncoding = \"hex\",\n ): string[] {\n const aipMessageBuffer = this.getAIPMessageBuffer(opReturn);\n const { address, signature } = this.signMessage(\n aipMessageBuffer,\n signingPath,\n );\n\n return opReturn.concat([\n Buffer.from(\"|\").toString(outputType),\n Buffer.from(AIP_BITCOM_ADDRESS).toString(outputType),\n Buffer.from(\"BITCOIN_ECDSA\").toString(outputType),\n Buffer.from(address).toString(outputType),\n Buffer.from(signature, \"base64\").toString(outputType),\n ]);\n }\n\n /**\n * Construct an AIP buffer from the op return data\n * @param opReturn\n * @returns {Buffer}\n */\n getAIPMessageBuffer(opReturn: string[]): Buffer {\n const buffers = [];\n if (opReturn[0].replace(\"0x\", \"\") !== \"6a\") {\n // include OP_RETURN in constructing the signature buffer\n buffers.push(Buffer.from(\"6a\", \"hex\"));\n }\n for (const op of opReturn) {\n buffers.push(Buffer.from(op.replace(\"0x\", \"\"), \"hex\"));\n }\n // add a trailing \"|\" - this is the AIP way\n buffers.push(Buffer.from(\"|\"));\n\n return Buffer.concat([...buffers] as unknown as Uint8Array[]);\n }\n\n /**\n * Get all signing keys for this identity\n */\n async getIdSigningKeys(): Promise<GetSigningKeysResponse> {\n const signingKeys = await this.getApiData<GetSigningKeysResponse>(\"/signing-keys\", {\n idKey: this.identityKey,\n });\n console.log(\"getIdSigningKeys\", signingKeys);\n\n return signingKeys;\n }\n\n /**\n * Get all attestations for the given attribute\n *\n * @param attribute\n */\n async getAttributeAttestations(attribute: string): Promise<GetAttestationResponse> {\n // This function needs to make a call to a BAP server to get all the attestations for this\n // identity for the given attribute\n const attestationHash = this.getAttestationHash(attribute);\n\n // get all BAP ATTEST records for the given attestationHash\n const attestations = await this.getApiData<GetAttestationResponse>(\"/attestation/get\", {\n hash: attestationHash,\n });\n console.log(\"getAttestations\", attribute, attestationHash, attestations);\n\n return attestations;\n }\n\n // /**\n // * Helper function to get attestation from a BAP API server\n // *\n // * @param apiUrl\n // * @param apiData\n // * @returns {Promise<any>}\n // */\n // async getApiData(apiUrl: string, apiData: any): Promise<any> {\n // \tconst url = `${this.#BAP_SERVER}${apiUrl}`;\n // \tconst response = await fetch(url, {\n // \t\tmethod: \"post\",\n // \t\theaders: {\n // \t\t\t\"Content-type\": \"application/json; charset=utf-8\",\n // \t\t\ttoken: this.#BAP_TOKEN,\n // \t\t\tformat: \"json\",\n // \t\t},\n // \t\tbody: JSON.stringify(apiData),\n // \t});\n // \treturn response.json();\n // }\n\n /**\n * Import an identity from a JSON object\n *\n * @param identity{{}}\n */\n import(identity: Identity | OldIdentity): void {\n this.idName = identity.name;\n this.description = identity.description || \"\";\n this.identityKey = identity.identityKey;\n this.#rootPath = identity.rootPath;\n this.rootAddress = identity.rootAddress;\n this.#previousPath = identity.previousPath;\n this.#currentPath = identity.currentPath;\n this.#idSeed = ('idSeed' in identity ? identity.idSeed : \"\") || \"\";\n this.identityAttributes = this.parseAttributes(identity.identityAttributes);\n }\n\n /**\n * Export this identity to a JSON object\n * @returns {{}}\n */\n export(): Identity {\n return {\n name: this.idName,\n description: this.description,\n identityKey: this.identityKey,\n rootPath: this.#rootPath,\n rootAddress: this.rootAddress,\n previousPath: this.#previousPath,\n currentPath: this.#currentPath,\n idSeed: this.#idSeed,\n identityAttributes: this.getAttributes(),\n lastIdPath: \"\",\n };\n }\n\n // New method to export a member-friendly backup, containing only the derived signing key\n exportMemberBackup(): MemberIdentity {\n const derivedKey = this.#HDPrivateKey.derive(this.#currentPath).privKey;\n return {\n name: this.idName,\n description: this.description,\n derivedPrivateKey: derivedKey.toString(),\n address: derivedKey.toPublicKey().toAddress(),\n identityAttributes: this.getAttributes(),\n };\n }\n\n // New method to derive a new member ID from the master HD key\n public newId(): MemberID {\n // Assuming incrementPath updates the internal current path\n this.incrementPath();\n const derivedKey = this.#HDPrivateKey.derive(this.#currentPath).privKey;\n return new MemberID(derivedKey, this.getAttributes());\n }\n}\n\nexport { MasterID };\n",
9
9
  "import { randomBytes } from 'node:crypto';\nimport type { PathPrefix } from \"./interface.js\";\n\nexport const Utils = {\n /**\n * Helper function for encoding strings to hex\n *\n * @param string\n * @returns {string}\n */\n hexEncode(string: string) {\n return `0x${Buffer.from(string).toString('hex')}`;\n },\n\n /**\n * Helper function for encoding strings to hex\n *\n * @param hexString string\n * @param encoding BufferEncoding\n * @returns {string}\n */\n hexDecode(hexString: string, encoding: BufferEncoding = 'utf8') {\n return Buffer.from(hexString.replace('0x', ''), 'hex').toString(encoding);\n },\n\n /**\n * Helper function to generate a random nonce\n *\n * @returns {string}\n */\n getRandomString(length = 32) {\n return randomBytes(length).toString('hex');\n },\n\n /**\n * Test whether the given string is hex\n *\n * @param value any\n * @returns {boolean}\n */\n isHex(value: string): boolean {\n if (typeof value !== 'string') {\n return false;\n }\n return /^[0-9a-fA-F]+$/.test(value);\n },\n\n /**\n * Get a signing path from a hex number\n *\n * @param hexString {string}\n * @param hardened {boolean} Whether to return a hardened path\n * @returns {string}\n */\n getSigningPathFromHex(hexString: string, hardened = true) {\n // \"m/0/0/1\"\n let signingPath = 'm';\n const signingHex = hexString.match(/.{1,8}/g);\n if (!signingHex) {\n throw new Error('Invalid hex string');\n }\n const maxNumber = 2147483648 - 1; // 0x80000000\n for (const hexNumber of signingHex) {\n let number = Number(`0x${hexNumber}`);\n if (number > maxNumber) number -= maxNumber;\n signingPath += `/${number}${(hardened ? \"'\" : '')}`;\n }\n\n return signingPath;\n },\n\n /**\n * Increment that second to last part from the given part, set the last part to 0\n *\n * @param path string\n * @returns {*}\n */\n getNextIdentityPath(path: string): PathPrefix {\n const pathValues = path.split('/');\n const secondToLastPart = pathValues[pathValues.length - 2];\n\n let hardened = false;\n if (secondToLastPart.match('\\'')) {\n hardened = true;\n }\n\n const nextPath = (Number(secondToLastPart.replace(/[^0-9]/g, '')) + 1).toString();\n pathValues[pathValues.length - 2] = nextPath + (hardened ? '\\'' : '');\n pathValues[pathValues.length - 1] = `0${hardened ? '\\'' : ''}`;\n\n return pathValues.join('/') as PathPrefix;\n },\n\n /**\n * Increment that last part of the given path\n *\n * @param path string\n * @returns {*}\n */\n getNextPath(path: string) {\n const pathValues = path.split('/');\n const lastPart = pathValues[pathValues.length - 1];\n let hardened = false;\n if (lastPart.match('\\'')) {\n hardened = true;\n }\n const nextPath = (Number(lastPart.replace(/[^0-9]/g, '')) + 1).toString();\n pathValues[pathValues.length - 1] = nextPath + (hardened ? '\\'' : '');\n return pathValues.join('/');\n },\n};\n",
10
10
  "import { BSM, type Signature, BigNumber, PrivateKey, Utils, Hash } from \"@bsv/sdk\";\n\nconst { toHex, toBase58, toArray } = Utils;\nconst { magicHash } = BSM;\nimport type { IdentityAttributes } from \"./interface\";\n\nexport interface MemberIdentity {\n name: string;\n description: string;\n derivedPrivateKey: string;\n address: string;\n identityAttributes: IdentityAttributes;\n}\n\nclass MemberID {\n private key: PrivateKey;\n public identityAttributes: IdentityAttributes;\n public address: string;\n public idName: string;\n public description: string;\n\n constructor(key: PrivateKey, identityAttributes: IdentityAttributes | string = {}) {\n this.key = key;\n // If identityAttributes is a string, parse it using parseStringUrns, otherwise use as is\n this.identityAttributes = typeof identityAttributes === 'string' ? this.parseStringUrns(identityAttributes) : identityAttributes;\n this.address = this.key.toAddress();\n this.idName = \"Member ID 1\";\n this.description = \"\";\n }\n\n // Basic message signing using the member's derived private key\n public signMessage(message: string | Buffer): { address: string; signature: string } {\n const msgBuffer = typeof message === 'string' ? Buffer.from(message) : message;\n const childPk = this.key;\n const address = childPk.toPublicKey().toString();\n // Sign using the raw message buffer directly\n const dummySig = BSM.sign(toArray(msgBuffer), childPk, 'raw') as Signature;\n const h = new BigNumber(magicHash(toArray(msgBuffer, \"utf8\")));\n const r = dummySig.CalculateRecoveryFactor(childPk.toPublicKey(), h);\n const signature = (BSM.sign(toArray(msgBuffer), childPk, 'raw') as Signature).toCompact(r, true, \"base64\") as string;\n return { address, signature };\n }\n \n // Return the member's public key\n public getPublicKey(): string {\n return this.key.toPublicKey().toString();\n }\n \n // Import the member identity from an object containing the derived private key and identity data\n public import(identity: MemberIdentity): void {\n this.idName = identity.name;\n this.description = identity.description;\n this.key = PrivateKey.fromString(identity.derivedPrivateKey);\n this.address = this.key.toAddress();\n this.identityAttributes = identity.identityAttributes;\n }\n\n static fromImport(identity: MemberIdentity): MemberID {\n const member = new MemberID(PrivateKey.fromString(identity.derivedPrivateKey));\n member.import(identity);\n return member;\n }\n\n // Export the member identity as an object containing the derived private key and identity data\n public export(): MemberIdentity {\n return {\n name: this.idName,\n description: this.description,\n derivedPrivateKey: this.key.toString(),\n address: this.address,\n identityAttributes: this.identityAttributes\n } as MemberIdentity;\n }\n \n // Helper to parse identity attributes from a string of URNs\n private parseStringUrns(urnIdentityAttributes: string): IdentityAttributes {\n const attrs: IdentityAttributes = {};\n const lines = urnIdentityAttributes.replace(/^[ \\t]+/gm, \"\").trim().split(\"\\n\");\n for (const line of lines) {\n const parts = line.split(\":\");\n if (parts.length >= 6 && parts[0] === \"urn\" && parts[1] === \"bap\" && parts[2] === \"id\") {\n attrs[parts[3]] = { value: parts[4], nonce: parts[5] };\n }\n }\n return attrs;\n }\n }\n\n export { MemberID };"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "63CF71C289EEF0B864756E2164756E21",
12
+ "mappings": "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",
13
+ "debugId": "6A60A376E5A4A51E64756E2164756E21",
14
14
  "names": []
15
15
  }
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{BSM as N,BigNumber as n,ECIES as d,HD as s,Signature as r}from"@bsv/sdk";import{Utils as i}from"@bsv/sdk";var l=async(j,$,J,q)=>{let Q=`${J}${j}`;return(await fetch(Q,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},U=(j,$)=>async(J,q)=>{return l(J,q,j,$)};var Y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",H=`0x${Buffer.from("1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT").toString("hex")}`,R="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",qj=`0x${Buffer.from("15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva").toString("hex")}`,x="https://api.sigmaidentity.com/v1",F=2147483647,C="m/424150'/0'/0'",G="m/424150'/2147483647'/2147483647'";import{BSM as M,Utils as h,BigNumber as S,ECIES as y,Hash as X,PublicKey as _}from"@bsv/sdk";import{randomBytes as b}from"crypto";var W={hexEncode(j){return`0x${Buffer.from(j).toString("hex")}`},hexDecode(j,$="utf8"){return Buffer.from(j.replace("0x",""),"hex").toString($)},getRandomString(j=32){return b(j).toString("hex")},isHex(j){if(typeof j!=="string")return!1;return/^[0-9a-fA-F]+$/.test(j)},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let Q=2147483647;for(let z of q){let Z=Number(`0x${z}`);if(Z>Q)Z-=Q;J+=`/${Z}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=Q+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=Q+(q?"'":""),$.join("/")}};import{BSM as T,BigNumber as p,PrivateKey as D,Utils as P}from"@bsv/sdk";var{toHex:wj,toBase58:Yj,toArray:B}=P,{magicHash:o}=T;class V{key;identityAttributes;address;idName;description;constructor(j,$={}){this.key=j,this.identityAttributes=typeof $==="string"?this.parseStringUrns($):$,this.address=this.key.toAddress(),this.idName="Member ID 1",this.description=""}signMessage(j){let $=typeof j==="string"?Buffer.from(j):j,J=this.key,q=J.toPublicKey().toString(),Q=T.sign(B($),J,"raw"),z=new p(o(B($,"utf8"))),Z=Q.CalculateRecoveryFactor(J.toPublicKey(),z),L=T.sign(B($),J,"raw").toCompact(Z,!0,"base64");return{address:q,signature:L}}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=D.fromString(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes}static fromImport(j){let $=new V(D.fromString(j.derivedPrivateKey));return $.import(j),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toString(),address:this.address,identityAttributes:this.identityAttributes}}parseStringUrns(j){let $={},J=j.replace(/^[ \t]+/gm,"").trim().split(`
3
- `);for(let q of J){let Q=q.split(":");if(Q.length>=6&&Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id")$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}}var{toArray:w,toHex:O,toBase58:u,toUTF8:I,toBase64:A}=h,{electrumDecrypt:K,electrumEncrypt:m}=y,{magicHash:g}=M;class f{#j;#J=x;#Q="";#$;#q;#z;#W;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){if(this.#W=J,J){let z=O(X.sha256(J,"utf8")),Z=W.getSigningPathFromHex(z);this.#j=j.derive(Z)}else this.#j=j;this.idName="ID 1",this.description="",this.#$=`${C}/0/0/0`,this.#q=`${C}/0/0/0`,this.#z=`${C}/0/0/1`;let q=this.#j.derive(this.#$);this.rootAddress=q.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);let Q={...$};this.identityAttributes=this.parseAttributes(Q),this.getApiData=U(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 $=O(X.sha256(j,"utf8"));return u(X.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(`
2
+ import{BSM as N,BigNumber as n,ECIES as d,HD as s,Signature as r}from"@bsv/sdk";import{Utils as i}from"@bsv/sdk";var l=async(j,$,J,q)=>{let Q=`${J}${j}`;return(await fetch(Q,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify($)})).json()},R=(j,$)=>async(J,q)=>{return l(J,q,j,$)};var Y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",H=`0x${Buffer.from("1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT").toString("hex")}`,x="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",qj=`0x${Buffer.from("15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva").toString("hex")}`,V="https://api.sigmaidentity.com/v1",F=2147483647,C="m/424150'/0'/0'",G="m/424150'/2147483647'/2147483647'";import{BSM as M,Utils as h,BigNumber as D,ECIES as y,Hash as X,PublicKey as _}from"@bsv/sdk";import{randomBytes as b}from"crypto";var W={hexEncode(j){return`0x${Buffer.from(j).toString("hex")}`},hexDecode(j,$="utf8"){return Buffer.from(j.replace("0x",""),"hex").toString($)},getRandomString(j=32){return b(j).toString("hex")},isHex(j){if(typeof j!=="string")return!1;return/^[0-9a-fA-F]+$/.test(j)},getSigningPathFromHex(j,$=!0){let J="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let Q=2147483647;for(let z of q){let Z=Number(`0x${z}`);if(Z>Q)Z-=Q;J+=`/${Z}${$?"'":""}`}return J},getNextIdentityPath(j){let $=j.split("/"),J=$[$.length-2],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=Q+(q?"'":""),$[$.length-1]=`0${q?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),J=$[$.length-1],q=!1;if(J.match("'"))q=!0;let Q=(Number(J.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=Q+(q?"'":""),$.join("/")}};import{BSM as T,BigNumber as p,PrivateKey as S,Utils as P}from"@bsv/sdk";var{toHex:wj,toBase58:Yj,toArray:B}=P,{magicHash:o}=T;class f{key;identityAttributes;address;idName;description;constructor(j,$={}){this.key=j,this.identityAttributes=typeof $==="string"?this.parseStringUrns($):$,this.address=this.key.toAddress(),this.idName="Member ID 1",this.description=""}signMessage(j){let $=typeof j==="string"?Buffer.from(j):j,J=this.key,q=J.toPublicKey().toString(),Q=T.sign(B($),J,"raw"),z=new p(o(B($,"utf8"))),Z=Q.CalculateRecoveryFactor(J.toPublicKey(),z),L=T.sign(B($),J,"raw").toCompact(Z,!0,"base64");return{address:q,signature:L}}getPublicKey(){return this.key.toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=S.fromString(j.derivedPrivateKey),this.address=this.key.toAddress(),this.identityAttributes=j.identityAttributes}static fromImport(j){let $=new f(S.fromString(j.derivedPrivateKey));return $.import(j),$}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toString(),address:this.address,identityAttributes:this.identityAttributes}}parseStringUrns(j){let $={},J=j.replace(/^[ \t]+/gm,"").trim().split(`
3
+ `);for(let q of J){let Q=q.split(":");if(Q.length>=6&&Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id")$[Q[3]]={value:Q[4],nonce:Q[5]}}return $}}var{toArray:w,toHex:O,toBase58:u,toUTF8:I,toBase64:A}=h,{electrumDecrypt:K,electrumEncrypt:g}=y,{magicHash:m}=M;class U{#j;#J=V;#Q="";#$;#q;#z;#W;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,$={},J=""){if(this.#W=J,J){let z=O(X.sha256(J,"utf8")),Z=W.getSigningPathFromHex(z);this.#j=j.derive(Z)}else this.#j=j;this.idName="ID 1",this.description="",this.#$=`${C}/0/0/0`,this.#q=`${C}/0/0/0`,this.#z=`${C}/0/0/1`;let q=this.#j.derive(this.#$);this.rootAddress=q.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);let Q={...$};this.identityAttributes=this.parseAttributes(Q),this.getApiData=R(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 $=O(X.sha256(j,"utf8"));return u(X.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(`
4
4
  `);for(let q of J){let z=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(z[0]==="urn"&&z[1]==="bap"&&z[2]==="id"&&z[3]&&z[4]&&z[5])$[z[3]]={value:z[4],nonce:z[5]}}return $}getIdentityKey(){return this.identityKey}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,$)}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)}unsetAttribute(j){delete this.identityAttributes[j]}getAttributeUrns(){let j="";for(let $ in this.identityAttributes){let J=this.getAttributeUrn($);if(J)j+=`${J}
5
- `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}addAttribute(j,$,J=""){let q=J;if(!J)q=W.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}set rootPath(j){if(this.#j){let $=j;if(j.split("/").length<5)$=`${C}${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)$=`${C}${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.#W}incrementPath(){this.currentPath=W.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 $=[Buffer.from(Y).toString("hex"),Buffer.from("ID").toString("hex"),Buffer.from(this.identityKey).toString("hex"),Buffer.from(this.getCurrentAddress()).toString("hex")];return this.signOpReturnWithAIP($,j||this.#q)}getAddress(j){return this.#j.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionPublicKey(){return this.#j.derive(this.#$).derive(G).privKey.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString("hex")}encrypt(j,$){let Q=this.#j.derive(this.#$).derive(G).privKey.toPublicKey(),z=$?_.fromString($):Q;return A(m(w(j),z,null))}decrypt(j,$){let q=this.#j.derive(this.#$).derive(G).privKey,Q=void 0;if($)Q=_.fromString($);return I(K(w(j,"base64"),q,Q))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=q.toPublicKey(),z=J?_.fromString(J):Q;return A(m(w(j),z,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=void 0;if(J)Q=_.fromString(J);return I(K(w(j,"base64"),q,Q))}getEncryptionPrivateKeyWithSeed(j){let $=O(X.sha256(j,"utf8")),J=W.getSigningPathFromHex($);return this.#j.derive(this.#$).derive(J).privKey}getAttestation(j){let $=X.sha256(j,"utf8");return`bap:attest:${O($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=X.sha256(J,"utf8");return O(q)}signMessage(j,$=""){let J;if(!(j instanceof Buffer))J=Buffer.from(j);else J=j;let q=$||this.#z,Q=this.#j.derive(q).privKey,z=Q.toAddress(),Z=M.sign(w(j),Q,"raw"),L=new S(g(w(j,"utf8"))),k=Z.CalculateRecoveryFactor(Q.toPublicKey(),L),E=M.sign(w(J),Q,"raw").toCompact(k,!0,"base64");return{address:z,signature:E}}signMessageWithSeed(j,$){let J=O(X.sha256($,"utf8")),q=W.getSigningPathFromHex(J),z=this.#j.derive(this.#$).derive(q),Z=z.privKey.toPublicKey().toAddress(),L=M.sign(w(j),z.privKey,"raw"),k=new S(g(w(j,"utf8"))),E=L.CalculateRecoveryFactor(z.privKey.toPublicKey(),k),c=M.sign(w(Buffer.from(j)),z.privKey,"raw").toCompact(E,!0,"base64");return{address:Z,signature:c}}signOpReturnWithAIP(j,$="",J="hex"){let q=this.getAIPMessageBuffer(j),{address:Q,signature:z}=this.signMessage(q,$);return j.concat([Buffer.from("|").toString(J),Buffer.from(R).toString(J),Buffer.from("BITCOIN_ECDSA").toString(J),Buffer.from(Q).toString(J),Buffer.from(z,"base64").toString(J)])}getAIPMessageBuffer(j){let $=[];if(j[0].replace("0x","")!=="6a")$.push(Buffer.from("6a","hex"));for(let J of j)$.push(Buffer.from(J.replace("0x",""),"hex"));return $.push(Buffer.from("|")),Buffer.concat([...$])}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.#W=("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.#W,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.#j.derive(this.#z).privKey;return{name:this.idName,description:this.description,derivedPrivateKey:j.toString(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes()}}newId(){this.incrementPath();let j=this.#j.derive(this.#z).privKey;return new V(j,this.getAttributes())}}var{toArray:v,toUTF8:a,toBase64:e}=i,{electrumEncrypt:t,electrumDecrypt:jj}=d;class $j{#j;#J={};#Q=x;#$="";#q="";getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No HDPrivateKey given");if(this.#j=s.fromString(j),$)this.#$=$;if(J)this.#Q=J;this.getApiData=U(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 Q=new f(this.#j,$,J);Q.BAP_SERVER=this.#Q,Q.BAP_TOKEN=this.#$,Q.rootPath=q,Q.currentPath=W.getNextPath(q);let z=Q.getIdentityKey();return this.#J[z]=Q,this.#q=q,this.#J[z]}removeId(j){delete this.#J[j]}getNextValidPath(){if(this.#q)return W.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 Q of J.ids){if(!Q.identityKey||!Q.identityAttributes||!Q.rootAddress)throw new Error("ID cannot be imported as it is not complete");let z=new f(this.#j,{},Q.idSeed);if(z.BAP_SERVER=this.#Q,z.BAP_TOKEN=this.#$,z.import(Q),q==="")q=z.currentPath;this.checkIdBelongs(z),this.#J[z.getIdentityKey()]=z}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 f(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 Q of q){if(!this.#J[Q])throw new Error(`Identity ${Q} not found`);J.ids.push(this.#J[Q].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(G);return e(t(v(j),$.pubKey,null))}decrypt(j){let $=this.#j.derive(G);return a(jj(v(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let Q=this.getId($);if(!Q)throw new Error("Could not find identity to attest with");let z=this.getAttestationBuffer(j,J,q),{address:Z,signature:L}=Q.signMessage(z);return this.createAttestationTransaction(j,J,Z,L,q)}verifyAttestationWithAIP(j){if(!Array.isArray(j)||j[0]!=="0x6a"||j[1]!==H)throw new Error("Not a valid BAP transaction");let $=j[7]==="0x44415441"?5:0,J={type:W.hexDecode(j[2]),hash:W.hexDecode(j[3]),sequence:W.hexDecode(j[4]),signingProtocol:W.hexDecode(j[7+$]),signingAddress:W.hexDecode(j[8+$]),signature:W.hexDecode(j[9+$],"base64")};if($&&j[3]===j[8])J.data=W.hexDecode(j[9]);try{let q=[];for(let z=0;z<6+$;z++)q.push(Buffer.from(j[z].replace("0x",""),"hex"));let Q=Buffer.concat(q);J.verified=this.verifySignature(Q,J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,Q=""){let z=["0x6a",W.hexEncode(Y)];if(z.push(W.hexEncode("ATTEST")),z.push(W.hexEncode(j)),z.push(W.hexEncode(`${$}`)),z.push("0x7c"),Q)z.push(W.hexEncode(Y)),z.push(W.hexEncode("DATA")),z.push(W.hexEncode(j)),z.push(W.hexEncode(Q)),z.push("0x7c");return z.push(W.hexEncode(R)),z.push(W.hexEncode("BITCOIN_ECDSA")),z.push(W.hexEncode(J)),z.push(`0x${Buffer.from(q,"base64").toString("hex")}`),z}getAttestationBuffer(j,$=0,J=""){let q=Buffer.from("");if(J)q=Buffer.concat([Buffer.from(Y),Buffer.from("DATA"),Buffer.from(j),Buffer.from(J),Buffer.from("7c","hex")]);return Buffer.concat([Buffer.from("6a","hex"),Buffer.from(Y),Buffer.from("ATTEST"),Buffer.from(j),Buffer.from(`${$}`),Buffer.from("7c","hex"),q])}verifySignature(j,$,J){let q=Buffer.isBuffer(j)?j:Buffer.from(j),Q=r.fromCompact(J,"base64"),z,Z=v(q.toString("hex"),"hex");for(let L=0;L<4;L++)try{if(z=Q.RecoverPublicKey(L,new n(N.magicHash(Z))),N.verify(Z,Q,z)&&z.toAddress()===$)return!0}catch(k){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let z=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(z?.status==="success"&&z?.result?.valid===!0)return!0;return!1}catch(z){return console.error("API call failed:",z),!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})}}export{f as MasterID,$j as BAP};
5
+ `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}addAttribute(j,$,J=""){let q=J;if(!J)q=W.getRandomString();this.identityAttributes[j]={value:$,nonce:q}}set rootPath(j){if(this.#j){let $=j;if(j.split("/").length<5)$=`${C}${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)$=`${C}${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.#W}incrementPath(){this.currentPath=W.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 $=[Buffer.from(Y).toString("hex"),Buffer.from("ID").toString("hex"),Buffer.from(this.identityKey).toString("hex"),Buffer.from(this.getCurrentAddress()).toString("hex")];return this.signOpReturnWithAIP($,j||this.#q)}getAddress(j){return this.#j.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionPublicKey(){return this.#j.derive(this.#$).derive(G).privKey.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString("hex")}encrypt(j,$){let Q=this.#j.derive(this.#$).derive(G).privKey.toPublicKey(),z=$?_.fromString($):Q;return A(g(w(j),z,null))}decrypt(j,$){let q=this.#j.derive(this.#$).derive(G).privKey,Q=void 0;if($)Q=_.fromString($);return I(K(w(j,"base64"),q,Q))}encryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=q.toPublicKey(),z=J?_.fromString(J):Q;return A(g(w(j),z,q))}decryptWithSeed(j,$,J){let q=this.getEncryptionPrivateKeyWithSeed($),Q=void 0;if(J)Q=_.fromString(J);return I(K(w(j,"base64"),q,Q))}getEncryptionPrivateKeyWithSeed(j){let $=O(X.sha256(j,"utf8")),J=W.getSigningPathFromHex($);return this.#j.derive(this.#$).derive(J).privKey}getAttestation(j){let $=X.sha256(j,"utf8");return`bap:attest:${O($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let J=this.getAttestation($),q=X.sha256(J,"utf8");return O(q)}signMessage(j,$=""){let J;if(!(j instanceof Buffer))J=Buffer.from(j);else J=j;let q=$||this.#z,Q=this.#j.derive(q).privKey,z=Q.toAddress(),Z=M.sign(w(j),Q,"raw"),L=new D(m(w(j,"utf8"))),k=Z.CalculateRecoveryFactor(Q.toPublicKey(),L),E=M.sign(w(J),Q,"raw").toCompact(k,!0,"base64");return{address:z,signature:E}}signMessageWithSeed(j,$){let J=O(X.sha256($,"utf8")),q=W.getSigningPathFromHex(J),z=this.#j.derive(this.#$).derive(q),Z=z.privKey.toPublicKey().toAddress(),L=M.sign(w(j),z.privKey,"raw"),k=new D(m(w(j,"utf8"))),E=L.CalculateRecoveryFactor(z.privKey.toPublicKey(),k),c=M.sign(w(Buffer.from(j)),z.privKey,"raw").toCompact(E,!0,"base64");return{address:Z,signature:c}}signOpReturnWithAIP(j,$="",J="hex"){let q=this.getAIPMessageBuffer(j),{address:Q,signature:z}=this.signMessage(q,$);return j.concat([Buffer.from("|").toString(J),Buffer.from(x).toString(J),Buffer.from("BITCOIN_ECDSA").toString(J),Buffer.from(Q).toString(J),Buffer.from(z,"base64").toString(J)])}getAIPMessageBuffer(j){let $=[];if(j[0].replace("0x","")!=="6a")$.push(Buffer.from("6a","hex"));for(let J of j)$.push(Buffer.from(J.replace("0x",""),"hex"));return $.push(Buffer.from("|")),Buffer.concat([...$])}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.#W=("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.#W,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.#j.derive(this.#z).privKey;return{name:this.idName,description:this.description,derivedPrivateKey:j.toString(),address:j.toPublicKey().toAddress(),identityAttributes:this.getAttributes()}}newId(){this.incrementPath();let j=this.#j.derive(this.#z).privKey;return new f(j,this.getAttributes())}}var{toArray:v,toUTF8:a,toBase64:e}=i,{electrumEncrypt:t,electrumDecrypt:jj}=d;class $j{#j;#J={};#Q=V;#$="";#q="";getApiData;constructor(j,$="",J=""){if(!j)throw new Error("No HDPrivateKey given");if(this.#j=s.fromString(j),$)this.#$=$;if(J)this.#Q=J;this.getApiData=R(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 Q=new U(this.#j,$,J);Q.BAP_SERVER=this.#Q,Q.BAP_TOKEN=this.#$,Q.rootPath=q,Q.currentPath=W.getNextPath(q);let z=Q.getIdentityKey();return this.#J[z]=Q,this.#q=q,this.#J[z]}removeId(j){delete this.#J[j]}getNextValidPath(){if(this.#q)return W.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 Q of J.ids){if(!Q.identityKey||!Q.identityAttributes||!Q.rootAddress)throw new Error("ID cannot be imported as it is not complete");let z=new U(this.#j,{},Q.idSeed);if(z.BAP_SERVER=this.#Q,z.BAP_TOKEN=this.#$,z.import(Q),q==="")q=z.currentPath;this.checkIdBelongs(z),this.#J[z.getIdentityKey()]=z}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 U(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 Q of q){if(!this.#J[Q])throw new Error(`Identity ${Q} not found`);J.ids.push(this.#J[Q].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(G);return e(t(v(j),$.pubKey,null))}decrypt(j){let $=this.#j.derive(G);return a(jj(v(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,J=0,q=""){let Q=this.getId($);if(!Q)throw new Error("Could not find identity to attest with");let z=this.getAttestationBuffer(j,J,q),{address:Z,signature:L}=Q.signMessage(z);return this.createAttestationTransaction(j,J,Z,L,q)}verifyAttestationWithAIP(j){if(!Array.isArray(j)||j[0]!=="0x6a"||j[1]!==H)throw new Error("Not a valid BAP transaction");let $=j[7]==="0x44415441"?5:0,J={type:W.hexDecode(j[2]),hash:W.hexDecode(j[3]),sequence:W.hexDecode(j[4]),signingProtocol:W.hexDecode(j[7+$]),signingAddress:W.hexDecode(j[8+$]),signature:W.hexDecode(j[9+$],"base64")};if($&&j[3]===j[8])J.data=W.hexDecode(j[9]);try{let q=[];for(let z=0;z<6+$;z++)q.push(Buffer.from(j[z].replace("0x",""),"hex"));let Q=Buffer.concat(q);J.verified=this.verifySignature(Q,J.signingAddress,J.signature)}catch(q){J.verified=!1}return J}createAttestationTransaction(j,$,J,q,Q=""){let z=["0x6a",W.hexEncode(Y)];if(z.push(W.hexEncode("ATTEST")),z.push(W.hexEncode(j)),z.push(W.hexEncode(`${$}`)),z.push("0x7c"),Q)z.push(W.hexEncode(Y)),z.push(W.hexEncode("DATA")),z.push(W.hexEncode(j)),z.push(W.hexEncode(Q)),z.push("0x7c");return z.push(W.hexEncode(x)),z.push(W.hexEncode("BITCOIN_ECDSA")),z.push(W.hexEncode(J)),z.push(`0x${Buffer.from(q,"base64").toString("hex")}`),z}getAttestationBuffer(j,$=0,J=""){let q=Buffer.from("");if(J)q=Buffer.concat([Buffer.from(Y),Buffer.from("DATA"),Buffer.from(j),Buffer.from(J),Buffer.from("7c","hex")]);return Buffer.concat([Buffer.from("6a","hex"),Buffer.from(Y),Buffer.from("ATTEST"),Buffer.from(j),Buffer.from(`${$}`),Buffer.from("7c","hex"),q])}verifySignature(j,$,J){let q=Buffer.isBuffer(j)?j:Buffer.from(j),Q=r.fromCompact(J,"base64"),z,Z=v(q.toString("hex"),"hex");for(let L=0;L<4;L++)try{if(z=Q.RecoverPublicKey(L,new n(N.magicHash(Z))),N.verify(Z,Q,z)&&z.toAddress()===$)return!0}catch(k){}return!1}async verifyChallengeSignature(j,$,J,q){if(!this.verifySignature(J,$,q))return!1;try{let z=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:J,signature:q});if(z?.status==="success"&&z?.result?.valid===!0)return!0;return!1}catch(z){return console.error("API call failed:",z),!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})}}export{f as MemberID,U as MasterID,$j as BAP};
7
7
 
8
- //# debugId=1D3171E9D890176264756E2164756E21
8
+ //# debugId=2611D71C4EE78D4664756E2164756E21
@@ -2,14 +2,14 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/api.ts", "../src/constants.ts", "../src/MasterID.ts", "../src/utils.ts", "../src/MemberID.ts"],
4
4
  "sourcesContent": [
5
- "import { BSM, BigNumber, ECIES, HD, type PublicKey, Signature } from \"@bsv/sdk\";\n\nimport { Utils as BSVUtils } from \"@bsv/sdk\";\nimport { type APIFetcher, apiFetcher } from \"./api\";\nimport type { AttestationValidResponse, GetAttestationResponse, GetIdentityByAddressResponse, GetIdentityResponse } from \"./apiTypes\";\nimport {\n AIP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS_HEX,\n BAP_SERVER,\n ENCRYPTION_PATH,\n} from \"./constants\";\nimport { MasterID } from \"./MasterID\";\nimport type { Attestation, Identity, IdentityAttributes, OldIdentity, PathPrefix } from \"./interface\";\nimport { Utils } from \"./utils\";\nconst { toArray, toUTF8, toBase64 } = BSVUtils;\nconst { electrumEncrypt, electrumDecrypt } = ECIES;\n\ntype Identities = { lastIdPath: string; ids: Identity[] };\n\n\n/**\n * BAP class\n *\n * Creates an instance of the BAP class and uses the given HDPrivateKey for all BAP operations.\n *\n * @param HDPrivateKey\n */\nexport class BAP {\n #HDPrivateKey;\n #ids: { [key: string]: MasterID } = {};\n #BAP_SERVER = BAP_SERVER;\n #BAP_TOKEN = \"\";\n #lastIdPath = \"\";\n getApiData: APIFetcher;\n\n constructor(HDPrivateKey: string, token = \"\", server = \"\") {\n if (!HDPrivateKey) {\n throw new Error(\"No HDPrivateKey given\");\n }\n this.#HDPrivateKey = HD.fromString(HDPrivateKey);\n\n if (token) {\n this.#BAP_TOKEN = token;\n }\n\n if (server) {\n this.#BAP_SERVER = server;\n }\n\n this.getApiData = apiFetcher(this.#BAP_SERVER, this.#BAP_TOKEN);\n }\n\n get lastIdPath(): string {\n return this.#lastIdPath;\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).pubKey.toString();\n }\n\n return this.#HDPrivateKey.pubKey.toString();\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getHdPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).toPublic().toString();\n }\n\n return this.#HDPrivateKey.toPublic().toString();\n }\n\n set BAP_SERVER(bapServer) {\n this.#BAP_SERVER = bapServer;\n for (const key in this.#ids) {\n this.#ids[key].BAP_SERVER = bapServer;\n }\n }\n\n get BAP_SERVER(): string {\n return this.#BAP_SERVER;\n }\n\n set BAP_TOKEN(token) {\n this.#BAP_TOKEN = token;\n for (const key in this.#ids) {\n // @ts-ignore - does not recognize private fields that can be set\n this.#ids[key].BAP_TOKEN = token;\n }\n }\n\n get BAP_TOKEN(): string {\n return this.#BAP_TOKEN;\n }\n\n /**\n * This function verifies that the given bapId matches the given root address\n * This is used as a data integrity check\n *\n * @param bapId MasterID instance\n */\n checkIdBelongs(bapId: MasterID): boolean {\n const derivedChild = this.#HDPrivateKey.derive(bapId.rootPath);\n const checkRootAddress = derivedChild.pubKey.toAddress();\n if (checkRootAddress !== bapId.rootAddress) {\n throw new Error(\"ID does not belong to this private key\");\n }\n\n return true;\n }\n\n /**\n * Returns a list of all the identity keys that are stored in this instance\n *\n * @returns {string[]}\n */\n listIds(): string[] {\n return Object.keys(this.#ids);\n }\n\n /**\n * Create a new Id and link it to this BAP instance\n *\n * This function uses the length of the #ids of this class to determine the next valid path.\n * If not all ids related to this HDPrivateKey have been loaded, determine the path externally\n * and pass it to newId when creating a new ID.\n *\n * @param path\n * @param identityAttributes\n * @param idSeed\n * @returns {*}\n */\n newId(path?: string, identityAttributes: IdentityAttributes = {}, idSeed = \"\"): MasterID {\n let pathToUse: string;\n if (!path) {\n // get next usable path for this key\n pathToUse = this.getNextValidPath();\n } else {\n pathToUse = path;\n }\n\n const newIdentity = new MasterID(\n this.#HDPrivateKey,\n identityAttributes,\n idSeed,\n );\n newIdentity.BAP_SERVER = this.#BAP_SERVER;\n newIdentity.BAP_TOKEN = this.#BAP_TOKEN;\n\n newIdentity.rootPath = pathToUse;\n newIdentity.currentPath = Utils.getNextPath(pathToUse);\n\n const idKey = newIdentity.getIdentityKey();\n this.#ids[idKey] = newIdentity;\n this.#lastIdPath = pathToUse;\n\n return this.#ids[idKey];\n }\n\n /**\n * Remove identity\n *\n * @param idKey\n * @returns {*}\n */\n removeId(idKey: string): void {\n delete this.#ids[idKey];\n }\n\n /**\n * Get the next valid path for the used HDPrivateKey and loaded #ids\n *\n * @returns {string}\n */\n getNextValidPath(): PathPrefix {\n // prefer hardened paths\n if (this.#lastIdPath) {\n return Utils.getNextIdentityPath(this.#lastIdPath);\n }\n\n return `/0'/${Object.keys(this.#ids).length}'/0'`;\n }\n\n /**\n * Get a certain Id\n *\n * @param identityKey\n * @returns {null}\n */\n getId(identityKey: string): MasterID | null {\n return this.#ids[identityKey] || null;\n }\n\n /**\n * This function is used when manipulating ID's, adding or removing attributes etc\n * First create an id through this class and then use getId to get it. Then you can add/edit or\n * increment the signing path and then re-set it with this function.\n *\n * Note: when you getId() from this class, you will be working on the same object as this class\n * has and any changes made will be propagated to the id in this class. When you call exportIds\n * your new changes will also be included, without having to setId().\n *\n * @param bapId\n */\n setId(bapId: MasterID): void {\n this.checkIdBelongs(bapId);\n this.#ids[bapId.getIdentityKey()] = bapId;\n }\n\n /**\n * This function is used to import IDs and attributes from some external storage\n *\n * The ID information should NOT be stored together with the HD private key !\n *\n * @param idData Array of ids that have been exported\n * @param encrypted Whether the data should be treated as being encrypted (default true)\n */\n importIds(idData: Identities | string, encrypted = true): void {\n if (encrypted && typeof idData === \"string\") {\n this.importEncryptedIds(idData);\n return;\n }\n const identity = idData as Identities\n if (!identity.lastIdPath) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n\n if (!identity.ids) {\n throw new Error(`ID data is not in the correct format: ${idData}`);\n }\n\n let lastIdPath = (idData as Identities).lastIdPath;\n for (const id of identity.ids) {\n if (!id.identityKey || !id.identityAttributes || !id.rootAddress) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n const importId = new MasterID(this.#HDPrivateKey, {}, id.idSeed);\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n if (lastIdPath === \"\") {\n lastIdPath = importId.currentPath;\n }\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n }\n\n this.#lastIdPath = lastIdPath;\n }\n\n importEncryptedIds(idData: string): void {\n // decrypt the ids array using ECIES\n const decrypted = this.decrypt(idData);\n const ids = JSON.parse(decrypted) as Identities;\n\n const isOldFormat = Array.isArray(ids)\n if (isOldFormat) {\n console.log(\"Importing old format:\\n\", ids)\n this.importOldIds(ids)\n return\n }\n if (typeof ids !== \"object\") {\n throw new Error(\"decrypted, but found unrecognized identities format\")\n }\n this.importIds(ids, false);\n }\n\n importOldIds(idData: OldIdentity[]): void {\n for (const id of idData) {\n const importId = new MasterID(\n this.#HDPrivateKey,\n {},\n id.idSeed ?? \"\"\n );\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n this.#lastIdPath = importId.currentPath;\n }\n }\n\n\n /**\n * Export identities. If no idKeys are provided, exports all identities.\n * @param idKeys Optional array of identity keys to export. If omitted, exports all identities.\n * @param encrypted Whether to encrypt the export data\n */\n // Overload signatures\n exportIds(idKeys?: string[], encrypted?: true): string;\n exportIds(idKeys: string[] | undefined, encrypted: false): Identities;\n exportIds(idKeys?: string[], encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n const keysToExport = idKeys || Object.keys(this.#ids);\n\n for (const key of keysToExport) {\n if (!this.#ids[key]) {\n throw new Error(`Identity ${key} not found`);\n }\n idData.ids.push(this.#ids[key].export());\n }\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n return idData;\n }\n\n\n /**\n * Export a given ID from this instance for external storage\n *\n * By default this function will encrypt the data, using a derivative child of the main HD key\n *\n * @param idKey The key of the identity to export\n * @param encrypted Whether the data should be encrypted (default true)\n * @returns {[]|*}\n */\n // Overload signatures\n exportId(idKey: string, encrypted?: true): string;\n exportId(idKey: string, encrypted: false): Identities;\n exportId(idKey: string, encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n idData.ids.push(this.#ids[idKey].export());\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n\n return idData\n }\n\n /**\n * Encrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n encrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toBase64(\n // @ts-ignore - you can remove the null when this is merged https://github.com/bitcoin-sv/ts-sdk/pull/123\n electrumEncrypt(toArray(string), derivedChild.pubKey, null),\n );\n }\n\n /**\n * Decrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n decrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toUTF8(\n electrumDecrypt(toArray(string, \"base64\"), derivedChild.privKey),\n );\n }\n\n /**\n * Sign an attestation for a user\n *\n * @param attestationHash The computed attestation hash for the user - this should be calculated with the MasterID class for an identity for the user\n * @param identityKey The identity key we are using for the signing\n * @param counter\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {string[]}\n */\n signAttestationWithAIP(\n attestationHash: string,\n identityKey: string,\n counter = 0,\n dataString = \"\",\n ) {\n const id = this.getId(identityKey);\n if (!id) {\n throw new Error(\"Could not find identity to attest with\");\n }\n\n const attestationBuffer = this.getAttestationBuffer(\n attestationHash,\n counter,\n dataString,\n );\n const { address, signature } = id.signMessage(attestationBuffer);\n\n return this.createAttestationTransaction(\n attestationHash,\n counter,\n address,\n signature,\n dataString,\n );\n }\n\n /**\n * Verify an AIP signed attestation for a user\n *\n * [\n * '0x6a',\n * '0x31424150537561506e66476e53424d33474c56397968785564596534764762644d54',\n * '0x415454455354',\n * '0x33656166366361396334313936356538353831366439336439643034333136393032376633396661623034386333633031333663343364663635376462383761',\n * '0x30',\n * '0x7c',\n * '0x313550636948473232534e4c514a584d6f5355615756693757537163376843667661',\n * '0x424954434f494e5f4543445341',\n * '0x31477531796d52567a595557634638776f6f506a7a4a4c764d383550795a64655876',\n * '0x20ef60c5555001ddb1039bb0f215e46571fcb39ee46f48b089d1c08b0304dbcb3366d8fdf8bafd82be24b5ac42dcd6a5e96c90705dd42e3ad918b1b47ac3ce6ac2'\n * ]\n *\n * @param tx Array of hex values for the OP_RETURN values\n * @returns {{}}\n */\n verifyAttestationWithAIP(tx: string[]): Attestation {\n if (\n !Array.isArray(tx) ||\n tx[0] !== \"0x6a\" ||\n tx[1] !== BAP_BITCOM_ADDRESS_HEX\n ) {\n throw new Error(\"Not a valid BAP transaction\");\n }\n\n const dataOffset = tx[7] === \"0x44415441\" ? 5 : 0; // DATA\n const attestation: Attestation = {\n type: Utils.hexDecode(tx[2]),\n hash: Utils.hexDecode(tx[3]),\n sequence: Utils.hexDecode(tx[4]),\n signingProtocol: Utils.hexDecode(tx[7 + dataOffset]),\n signingAddress: Utils.hexDecode(tx[8 + dataOffset]),\n signature: Utils.hexDecode(tx[9 + dataOffset], \"base64\"),\n };\n\n if (dataOffset && tx[3] === tx[8]) {\n // valid data addition\n attestation.data = Utils.hexDecode(tx[9]);\n }\n\n try {\n const signatureBufferStatements: Buffer[] = [];\n for (let i = 0; i < 6 + dataOffset; i++) {\n signatureBufferStatements.push(\n Buffer.from(tx[i].replace(\"0x\", \"\"), \"hex\"),\n );\n }\n const attestationBuffer = Buffer.concat(signatureBufferStatements as unknown as Uint8Array[]);\n attestation.verified = this.verifySignature(\n attestationBuffer,\n attestation.signingAddress,\n attestation.signature,\n );\n } catch (e) {\n attestation.verified = false;\n }\n\n return attestation;\n }\n\n /**\n * For BAP attestations we use all fields for the attestation\n *\n * @param attestationHash\n * @param counter\n * @param address\n * @param signature\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {[string]}\n */\n createAttestationTransaction(\n attestationHash: string,\n counter: number,\n address: string,\n signature: string,\n dataString = \"\",\n ): string[] {\n const transaction = [\"0x6a\", Utils.hexEncode(BAP_BITCOM_ADDRESS)];\n transaction.push(Utils.hexEncode(\"ATTEST\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(`${counter}`));\n transaction.push(\"0x7c\"); // |\n if (dataString) {\n // data should be a string, either encrypted or stringified JSON if applicable\n transaction.push(Utils.hexEncode(BAP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"DATA\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(dataString));\n transaction.push(\"0x7c\"); // |\n }\n transaction.push(Utils.hexEncode(AIP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"BITCOIN_ECDSA\"));\n transaction.push(Utils.hexEncode(address));\n transaction.push(`0x${Buffer.from(signature, \"base64\").toString(\"hex\")}`);\n\n return transaction;\n }\n\n /**\n * This is a re-creation of how the bitcoinfiles-sdk creates a hash to sign for AIP\n *\n * @param attestationHash\n * @param counter\n * @param dataString Optional data string\n * @returns {Buffer}\n */\n getAttestationBuffer(\n attestationHash: string,\n counter = 0,\n dataString = \"\",\n ): Buffer {\n // re-create how AIP creates the buffer to sign\n let dataStringBuffer = Buffer.from(\"\");\n if (dataString) {\n dataStringBuffer = Buffer.concat([\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"DATA\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(dataString) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n ]);\n }\n return Buffer.concat([\n Buffer.from(\"6a\", \"hex\") as unknown as Uint8Array, // OP_RETURN\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"ATTEST\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(`${counter}`) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n dataStringBuffer as unknown as Uint8Array,\n ]);\n }\n\n /**\n * Verify that the identity challenge is signed by the address\n *\n * @param message Buffer or utf-8 string\n * @param address Bitcoin address of signee\n * @param signature Signature base64 string\n *\n * @return boolean\n */\n verifySignature(\n message: string | Buffer,\n address: string,\n signature: string,\n ): boolean {\n // check the signature against the challenge\n const messageBuffer = Buffer.isBuffer(message)\n ? message\n : Buffer.from(message);\n const sig = Signature.fromCompact(signature, \"base64\");\n let publicKey: PublicKey | undefined;\n const msg = toArray(messageBuffer.toString(\"hex\"), \"hex\");\n for (let recovery = 0; recovery < 4; recovery++) {\n try {\n publicKey = sig.RecoverPublicKey(\n recovery,\n new BigNumber(BSM.magicHash(msg)),\n );\n const sigFitsPubkey = BSM.verify(msg, sig, publicKey);\n if (sigFitsPubkey && publicKey.toAddress() === address) {\n return true;\n }\n } catch (e) {\n // try next recovery\n }\n }\n return false;\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param idKey\n * @param address\n * @param challenge\n * @param signature\n *\n * @returns {Promise<boolean|*>}\n */\n async verifyChallengeSignature(\n idKey: string,\n address: string,\n challenge: string,\n signature: string,\n ): Promise<boolean> {\n // first we test locally before sending to server\n const localVerification = this.verifySignature(challenge, address, signature);\n\n if (!localVerification) {\n return false;\n }\n\n try {\n const response = await this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n idKey,\n address,\n challenge,\n signature,\n });\n\n // Ensure we have a valid response with the expected structure\n if (response?.status === 'success' && response?.result?.valid === true) {\n return true;\n }\n\n return false;\n } catch (error) {\n console.error('API call failed:', error);\n return false;\n }\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param tx\n * @returns {Promise<boolean|*>}\n */\n async isValidAttestationTransaction(tx: string[]): Promise<AttestationValidResponse | false> {\n if (this.verifyAttestationWithAIP(tx)) {\n return this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n tx,\n });\n }\n return false;\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param address\n * @returns {Promise<*>}\n */\n async getIdentityFromAddress(address: string): Promise<GetIdentityByAddressResponse> {\n return this.getApiData<GetIdentityByAddressResponse>(\"/identity/from-address\", {\n address,\n });\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param idKey\n * @returns {Promise<*>}\n */\n async getIdentity(idKey: string): Promise<GetIdentityResponse> {\n return this.getApiData<GetIdentityResponse>(\"/identity/get\", {\n idKey,\n });\n }\n\n /**\n * Get all attestations for the given attestation hash\n *\n * @param attestationHash\n */\n async getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse> {\n // get all BAP ATTEST records for the given attestationHash\n return this.getApiData<GetAttestationResponse>(\"/attestations\", {\n hash: attestationHash,\n });\n }\n\n\n};\n\nexport { MasterID };\nexport type { Attestation, Identity, IdentityAttributes, PathPrefix };\n\n",
5
+ "import { BSM, BigNumber, ECIES, HD, type PublicKey, Signature } from \"@bsv/sdk\";\n\nimport { Utils as BSVUtils } from \"@bsv/sdk\";\nimport { type APIFetcher, apiFetcher } from \"./api\";\nimport type { AttestationValidResponse, GetAttestationResponse, GetIdentityByAddressResponse, GetIdentityResponse } from \"./apiTypes\";\nimport {\n AIP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS_HEX,\n BAP_SERVER,\n ENCRYPTION_PATH,\n} from \"./constants\";\nimport { MasterID } from \"./MasterID\";\nimport type { Attestation, Identity, IdentityAttributes, OldIdentity, PathPrefix } from \"./interface\";\nimport { Utils } from \"./utils\";\nimport { MemberID } from \"./MemberID\";\nconst { toArray, toUTF8, toBase64 } = BSVUtils;\nconst { electrumEncrypt, electrumDecrypt } = ECIES;\n\ntype Identities = { lastIdPath: string; ids: Identity[] };\n\n\n/**\n * BAP class\n *\n * Creates an instance of the BAP class and uses the given HDPrivateKey for all BAP operations.\n *\n * @param HDPrivateKey\n */\nexport class BAP {\n #HDPrivateKey;\n #ids: { [key: string]: MasterID } = {};\n #BAP_SERVER = BAP_SERVER;\n #BAP_TOKEN = \"\";\n #lastIdPath = \"\";\n getApiData: APIFetcher;\n\n constructor(HDPrivateKey: string, token = \"\", server = \"\") {\n if (!HDPrivateKey) {\n throw new Error(\"No HDPrivateKey given\");\n }\n this.#HDPrivateKey = HD.fromString(HDPrivateKey);\n\n if (token) {\n this.#BAP_TOKEN = token;\n }\n\n if (server) {\n this.#BAP_SERVER = server;\n }\n\n this.getApiData = apiFetcher(this.#BAP_SERVER, this.#BAP_TOKEN);\n }\n\n get lastIdPath(): string {\n return this.#lastIdPath;\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).pubKey.toString();\n }\n\n return this.#HDPrivateKey.pubKey.toString();\n }\n\n /**\n * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty\n *\n * @param childPath Full derivation path for this child\n * @returns {*}\n */\n getHdPublicKey(childPath = \"\"): string {\n if (childPath) {\n return this.#HDPrivateKey.derive(childPath).toPublic().toString();\n }\n\n return this.#HDPrivateKey.toPublic().toString();\n }\n\n set BAP_SERVER(bapServer) {\n this.#BAP_SERVER = bapServer;\n for (const key in this.#ids) {\n this.#ids[key].BAP_SERVER = bapServer;\n }\n }\n\n get BAP_SERVER(): string {\n return this.#BAP_SERVER;\n }\n\n set BAP_TOKEN(token) {\n this.#BAP_TOKEN = token;\n for (const key in this.#ids) {\n // @ts-ignore - does not recognize private fields that can be set\n this.#ids[key].BAP_TOKEN = token;\n }\n }\n\n get BAP_TOKEN(): string {\n return this.#BAP_TOKEN;\n }\n\n /**\n * This function verifies that the given bapId matches the given root address\n * This is used as a data integrity check\n *\n * @param bapId MasterID instance\n */\n checkIdBelongs(bapId: MasterID): boolean {\n const derivedChild = this.#HDPrivateKey.derive(bapId.rootPath);\n const checkRootAddress = derivedChild.pubKey.toAddress();\n if (checkRootAddress !== bapId.rootAddress) {\n throw new Error(\"ID does not belong to this private key\");\n }\n\n return true;\n }\n\n /**\n * Returns a list of all the identity keys that are stored in this instance\n *\n * @returns {string[]}\n */\n listIds(): string[] {\n return Object.keys(this.#ids);\n }\n\n /**\n * Create a new Id and link it to this BAP instance\n *\n * This function uses the length of the #ids of this class to determine the next valid path.\n * If not all ids related to this HDPrivateKey have been loaded, determine the path externally\n * and pass it to newId when creating a new ID.\n *\n * @param path\n * @param identityAttributes\n * @param idSeed\n * @returns {*}\n */\n newId(path?: string, identityAttributes: IdentityAttributes = {}, idSeed = \"\"): MasterID {\n let pathToUse: string;\n if (!path) {\n // get next usable path for this key\n pathToUse = this.getNextValidPath();\n } else {\n pathToUse = path;\n }\n\n const newIdentity = new MasterID(\n this.#HDPrivateKey,\n identityAttributes,\n idSeed,\n );\n newIdentity.BAP_SERVER = this.#BAP_SERVER;\n newIdentity.BAP_TOKEN = this.#BAP_TOKEN;\n\n newIdentity.rootPath = pathToUse;\n newIdentity.currentPath = Utils.getNextPath(pathToUse);\n\n const idKey = newIdentity.getIdentityKey();\n this.#ids[idKey] = newIdentity;\n this.#lastIdPath = pathToUse;\n\n return this.#ids[idKey];\n }\n\n /**\n * Remove identity\n *\n * @param idKey\n * @returns {*}\n */\n removeId(idKey: string): void {\n delete this.#ids[idKey];\n }\n\n /**\n * Get the next valid path for the used HDPrivateKey and loaded #ids\n *\n * @returns {string}\n */\n getNextValidPath(): PathPrefix {\n // prefer hardened paths\n if (this.#lastIdPath) {\n return Utils.getNextIdentityPath(this.#lastIdPath);\n }\n\n return `/0'/${Object.keys(this.#ids).length}'/0'`;\n }\n\n /**\n * Get a certain Id\n *\n * @param identityKey\n * @returns {null}\n */\n getId(identityKey: string): MasterID | null {\n return this.#ids[identityKey] || null;\n }\n\n /**\n * This function is used when manipulating ID's, adding or removing attributes etc\n * First create an id through this class and then use getId to get it. Then you can add/edit or\n * increment the signing path and then re-set it with this function.\n *\n * Note: when you getId() from this class, you will be working on the same object as this class\n * has and any changes made will be propagated to the id in this class. When you call exportIds\n * your new changes will also be included, without having to setId().\n *\n * @param bapId\n */\n setId(bapId: MasterID): void {\n this.checkIdBelongs(bapId);\n this.#ids[bapId.getIdentityKey()] = bapId;\n }\n\n /**\n * This function is used to import IDs and attributes from some external storage\n *\n * The ID information should NOT be stored together with the HD private key !\n *\n * @param idData Array of ids that have been exported\n * @param encrypted Whether the data should be treated as being encrypted (default true)\n */\n importIds(idData: Identities | string, encrypted = true): void {\n if (encrypted && typeof idData === \"string\") {\n this.importEncryptedIds(idData);\n return;\n }\n const identity = idData as Identities\n if (!identity.lastIdPath) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n\n if (!identity.ids) {\n throw new Error(`ID data is not in the correct format: ${idData}`);\n }\n\n let lastIdPath = (idData as Identities).lastIdPath;\n for (const id of identity.ids) {\n if (!id.identityKey || !id.identityAttributes || !id.rootAddress) {\n throw new Error(\"ID cannot be imported as it is not complete\");\n }\n const importId = new MasterID(this.#HDPrivateKey, {}, id.idSeed);\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n if (lastIdPath === \"\") {\n lastIdPath = importId.currentPath;\n }\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n }\n\n this.#lastIdPath = lastIdPath;\n }\n\n importEncryptedIds(idData: string): void {\n // decrypt the ids array using ECIES\n const decrypted = this.decrypt(idData);\n const ids = JSON.parse(decrypted) as Identities;\n\n const isOldFormat = Array.isArray(ids)\n if (isOldFormat) {\n console.log(\"Importing old format:\\n\", ids)\n this.importOldIds(ids)\n return\n }\n if (typeof ids !== \"object\") {\n throw new Error(\"decrypted, but found unrecognized identities format\")\n }\n this.importIds(ids, false);\n }\n\n importOldIds(idData: OldIdentity[]): void {\n for (const id of idData) {\n const importId = new MasterID(\n this.#HDPrivateKey,\n {},\n id.idSeed ?? \"\"\n );\n importId.BAP_SERVER = this.#BAP_SERVER;\n importId.BAP_TOKEN = this.#BAP_TOKEN;\n importId.import(id);\n\n this.checkIdBelongs(importId);\n this.#ids[importId.getIdentityKey()] = importId;\n this.#lastIdPath = importId.currentPath;\n }\n }\n\n\n /**\n * Export identities. If no idKeys are provided, exports all identities.\n * @param idKeys Optional array of identity keys to export. If omitted, exports all identities.\n * @param encrypted Whether to encrypt the export data\n */\n // Overload signatures\n exportIds(idKeys?: string[], encrypted?: true): string;\n exportIds(idKeys: string[] | undefined, encrypted: false): Identities;\n exportIds(idKeys?: string[], encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n const keysToExport = idKeys || Object.keys(this.#ids);\n\n for (const key of keysToExport) {\n if (!this.#ids[key]) {\n throw new Error(`Identity ${key} not found`);\n }\n idData.ids.push(this.#ids[key].export());\n }\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n return idData;\n }\n\n\n /**\n * Export a given ID from this instance for external storage\n *\n * By default this function will encrypt the data, using a derivative child of the main HD key\n *\n * @param idKey The key of the identity to export\n * @param encrypted Whether the data should be encrypted (default true)\n * @returns {[]|*}\n */\n // Overload signatures\n exportId(idKey: string, encrypted?: true): string;\n exportId(idKey: string, encrypted: false): Identities;\n exportId(idKey: string, encrypted = true): Identities | string {\n const idData: Identities = {\n lastIdPath: this.#lastIdPath,\n ids: [] as Identity[],\n };\n\n idData.ids.push(this.#ids[idKey].export());\n\n if (encrypted) {\n return this.encrypt(JSON.stringify(idData));\n }\n\n return idData\n }\n\n /**\n * Encrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n encrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toBase64(\n // @ts-ignore - you can remove the null when this is merged https://github.com/bitcoin-sv/ts-sdk/pull/123\n electrumEncrypt(toArray(string), derivedChild.pubKey, null),\n );\n }\n\n /**\n * Decrypt a string of data\n *\n * @param string\n * @returns {string}\n */\n decrypt(string: string): string {\n const derivedChild = this.#HDPrivateKey.derive(ENCRYPTION_PATH);\n return toUTF8(\n electrumDecrypt(toArray(string, \"base64\"), derivedChild.privKey),\n );\n }\n\n /**\n * Sign an attestation for a user\n *\n * @param attestationHash The computed attestation hash for the user - this should be calculated with the MasterID class for an identity for the user\n * @param identityKey The identity key we are using for the signing\n * @param counter\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {string[]}\n */\n signAttestationWithAIP(\n attestationHash: string,\n identityKey: string,\n counter = 0,\n dataString = \"\",\n ) {\n const id = this.getId(identityKey);\n if (!id) {\n throw new Error(\"Could not find identity to attest with\");\n }\n\n const attestationBuffer = this.getAttestationBuffer(\n attestationHash,\n counter,\n dataString,\n );\n const { address, signature } = id.signMessage(attestationBuffer);\n\n return this.createAttestationTransaction(\n attestationHash,\n counter,\n address,\n signature,\n dataString,\n );\n }\n\n /**\n * Verify an AIP signed attestation for a user\n *\n * [\n * '0x6a',\n * '0x31424150537561506e66476e53424d33474c56397968785564596534764762644d54',\n * '0x415454455354',\n * '0x33656166366361396334313936356538353831366439336439643034333136393032376633396661623034386333633031333663343364663635376462383761',\n * '0x30',\n * '0x7c',\n * '0x313550636948473232534e4c514a584d6f5355615756693757537163376843667661',\n * '0x424954434f494e5f4543445341',\n * '0x31477531796d52567a595557634638776f6f506a7a4a4c764d383550795a64655876',\n * '0x20ef60c5555001ddb1039bb0f215e46571fcb39ee46f48b089d1c08b0304dbcb3366d8fdf8bafd82be24b5ac42dcd6a5e96c90705dd42e3ad918b1b47ac3ce6ac2'\n * ]\n *\n * @param tx Array of hex values for the OP_RETURN values\n * @returns {{}}\n */\n verifyAttestationWithAIP(tx: string[]): Attestation {\n if (\n !Array.isArray(tx) ||\n tx[0] !== \"0x6a\" ||\n tx[1] !== BAP_BITCOM_ADDRESS_HEX\n ) {\n throw new Error(\"Not a valid BAP transaction\");\n }\n\n const dataOffset = tx[7] === \"0x44415441\" ? 5 : 0; // DATA\n const attestation: Attestation = {\n type: Utils.hexDecode(tx[2]),\n hash: Utils.hexDecode(tx[3]),\n sequence: Utils.hexDecode(tx[4]),\n signingProtocol: Utils.hexDecode(tx[7 + dataOffset]),\n signingAddress: Utils.hexDecode(tx[8 + dataOffset]),\n signature: Utils.hexDecode(tx[9 + dataOffset], \"base64\"),\n };\n\n if (dataOffset && tx[3] === tx[8]) {\n // valid data addition\n attestation.data = Utils.hexDecode(tx[9]);\n }\n\n try {\n const signatureBufferStatements: Buffer[] = [];\n for (let i = 0; i < 6 + dataOffset; i++) {\n signatureBufferStatements.push(\n Buffer.from(tx[i].replace(\"0x\", \"\"), \"hex\"),\n );\n }\n const attestationBuffer = Buffer.concat(signatureBufferStatements as unknown as Uint8Array[]);\n attestation.verified = this.verifySignature(\n attestationBuffer,\n attestation.signingAddress,\n attestation.signature,\n );\n } catch (e) {\n attestation.verified = false;\n }\n\n return attestation;\n }\n\n /**\n * For BAP attestations we use all fields for the attestation\n *\n * @param attestationHash\n * @param counter\n * @param address\n * @param signature\n * @param dataString Optional data string that will be appended to the BAP attestation\n * @returns {[string]}\n */\n createAttestationTransaction(\n attestationHash: string,\n counter: number,\n address: string,\n signature: string,\n dataString = \"\",\n ): string[] {\n const transaction = [\"0x6a\", Utils.hexEncode(BAP_BITCOM_ADDRESS)];\n transaction.push(Utils.hexEncode(\"ATTEST\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(`${counter}`));\n transaction.push(\"0x7c\"); // |\n if (dataString) {\n // data should be a string, either encrypted or stringified JSON if applicable\n transaction.push(Utils.hexEncode(BAP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"DATA\"));\n transaction.push(Utils.hexEncode(attestationHash));\n transaction.push(Utils.hexEncode(dataString));\n transaction.push(\"0x7c\"); // |\n }\n transaction.push(Utils.hexEncode(AIP_BITCOM_ADDRESS));\n transaction.push(Utils.hexEncode(\"BITCOIN_ECDSA\"));\n transaction.push(Utils.hexEncode(address));\n transaction.push(`0x${Buffer.from(signature, \"base64\").toString(\"hex\")}`);\n\n return transaction;\n }\n\n /**\n * This is a re-creation of how the bitcoinfiles-sdk creates a hash to sign for AIP\n *\n * @param attestationHash\n * @param counter\n * @param dataString Optional data string\n * @returns {Buffer}\n */\n getAttestationBuffer(\n attestationHash: string,\n counter = 0,\n dataString = \"\",\n ): Buffer {\n // re-create how AIP creates the buffer to sign\n let dataStringBuffer = Buffer.from(\"\");\n if (dataString) {\n dataStringBuffer = Buffer.concat([\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"DATA\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(dataString) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n ]);\n }\n return Buffer.concat([\n Buffer.from(\"6a\", \"hex\") as unknown as Uint8Array, // OP_RETURN\n Buffer.from(BAP_BITCOM_ADDRESS) as unknown as Uint8Array,\n Buffer.from(\"ATTEST\") as unknown as Uint8Array,\n Buffer.from(attestationHash) as unknown as Uint8Array,\n Buffer.from(`${counter}`) as unknown as Uint8Array,\n Buffer.from(\"7c\", \"hex\") as unknown as Uint8Array,\n dataStringBuffer as unknown as Uint8Array,\n ]);\n }\n\n /**\n * Verify that the identity challenge is signed by the address\n *\n * @param message Buffer or utf-8 string\n * @param address Bitcoin address of signee\n * @param signature Signature base64 string\n *\n * @return boolean\n */\n verifySignature(\n message: string | Buffer,\n address: string,\n signature: string,\n ): boolean {\n // check the signature against the challenge\n const messageBuffer = Buffer.isBuffer(message)\n ? message\n : Buffer.from(message);\n const sig = Signature.fromCompact(signature, \"base64\");\n let publicKey: PublicKey | undefined;\n const msg = toArray(messageBuffer.toString(\"hex\"), \"hex\");\n for (let recovery = 0; recovery < 4; recovery++) {\n try {\n publicKey = sig.RecoverPublicKey(\n recovery,\n new BigNumber(BSM.magicHash(msg)),\n );\n const sigFitsPubkey = BSM.verify(msg, sig, publicKey);\n if (sigFitsPubkey && publicKey.toAddress() === address) {\n return true;\n }\n } catch (e) {\n // try next recovery\n }\n }\n return false;\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param idKey\n * @param address\n * @param challenge\n * @param signature\n *\n * @returns {Promise<boolean|*>}\n */\n async verifyChallengeSignature(\n idKey: string,\n address: string,\n challenge: string,\n signature: string,\n ): Promise<boolean> {\n // first we test locally before sending to server\n const localVerification = this.verifySignature(challenge, address, signature);\n\n if (!localVerification) {\n return false;\n }\n\n try {\n const response = await this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n idKey,\n address,\n challenge,\n signature,\n });\n\n // Ensure we have a valid response with the expected structure\n if (response?.status === 'success' && response?.result?.valid === true) {\n return true;\n }\n\n return false;\n } catch (error) {\n console.error('API call failed:', error);\n return false;\n }\n }\n\n /**\n * Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the\n * identity signing is also valid at the time of signing\n *\n * @param tx\n * @returns {Promise<boolean|*>}\n */\n async isValidAttestationTransaction(tx: string[]): Promise<AttestationValidResponse | false> {\n if (this.verifyAttestationWithAIP(tx)) {\n return this.getApiData<AttestationValidResponse>(\"/attestation/valid\", {\n tx,\n });\n }\n return false;\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param address\n * @returns {Promise<*>}\n */\n async getIdentityFromAddress(address: string): Promise<GetIdentityByAddressResponse> {\n return this.getApiData<GetIdentityByAddressResponse>(\"/identity/from-address\", {\n address,\n });\n }\n\n /**\n * Get all signing keys for the given idKey\n *\n * @param idKey\n * @returns {Promise<*>}\n */\n async getIdentity(idKey: string): Promise<GetIdentityResponse> {\n return this.getApiData<GetIdentityResponse>(\"/identity/get\", {\n idKey,\n });\n }\n\n /**\n * Get all attestations for the given attestation hash\n *\n * @param attestationHash\n */\n async getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse> {\n // get all BAP ATTEST records for the given attestationHash\n return this.getApiData<GetAttestationResponse>(\"/attestations\", {\n hash: attestationHash,\n });\n }\n\n\n};\n\nexport { MasterID, MemberID };\nexport type { Attestation, Identity, IdentityAttributes, PathPrefix };\n\n",
6
6
  "\n/**\n\t * Helper function to get attestation from a BAP API server\n\t *\n\t * @param apiUrl\n\t * @param apiData\n\t * @returns {Promise<any>}\n\t */\nexport const getApiData = async <T>(apiUrl: string, apiData: unknown, server: string, token: string): Promise<T> => {\n const url = `${server}${apiUrl}`;\n const response = await fetch(url, {\n method: \"post\",\n headers: {\n \"Content-type\": \"application/json; charset=utf-8\",\n token,\n format: \"json\",\n },\n body: JSON.stringify(apiData),\n });\n\n return response.json();\n}\n\nexport type APIFetcher = <T>(url: string, data: unknown) => Promise<T>;\n\nexport const apiFetcher = (host: string, token: string): APIFetcher => async <T>(url: string, data: unknown): Promise<T> => {\n return getApiData<T>(url, data, host, token);\n}",
7
7
  "export const BAP_BITCOM_ADDRESS = '1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT';\nexport const BAP_BITCOM_ADDRESS_HEX = `0x${Buffer.from(BAP_BITCOM_ADDRESS).toString('hex')}`;\nexport const AIP_BITCOM_ADDRESS = '15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva';\nexport const AIP_BITCOM_ADDRESS_HEX = `0x${Buffer.from(AIP_BITCOM_ADDRESS).toString('hex')}`;\nexport const BAP_SERVER = 'https://api.sigmaidentity.com/v1';\nexport const MAX_INT = 2147483648 - 1; // 0x80000000\n\n// This is just a choice for this library and could be anything else if so needed/wanted\n// but it is advisable to use the same derivation between libraries for compatibility\nexport const SIGNING_PATH_PREFIX = 'm/424150\\'/0\\'/0\\''; // BAP in hex\nexport const ENCRYPTION_PATH = `m/424150'/${MAX_INT}'/${MAX_INT}'`;\n",
8
8
  "import { BSM, Utils as BSVUtils, BigNumber, ECIES, type HD, Hash, PublicKey, type Signature } from \"@bsv/sdk\";\n\nimport { type APIFetcher, apiFetcher } from \"./api\";\nimport type { GetAttestationResponse, GetSigningKeysResponse } from \"./apiTypes\";\nimport {\n AIP_BITCOM_ADDRESS,\n BAP_BITCOM_ADDRESS,\n BAP_SERVER,\n ENCRYPTION_PATH,\n MAX_INT,\n SIGNING_PATH_PREFIX,\n} from \"./constants\";\nimport type {\n Identity,\n IdentityAttribute,\n IdentityAttributes,\n OldIdentity,\n} from \"./interface\";\nimport { Utils } from \"./utils\";\nimport { MemberID, type MemberIdentity } from './MemberID';\nconst { toArray, toHex, toBase58, toUTF8, toBase64 } = BSVUtils;\nconst { electrumDecrypt, electrumEncrypt } = ECIES;\nconst { magicHash } = BSM;\n/**\n * MasterID class\n *\n * This class should be used in conjunction with the BAP class\n *\n * @type {MasterID}\n */\nclass MasterID {\n #HDPrivateKey: HD;\n #BAP_SERVER: string = BAP_SERVER;\n #BAP_TOKEN = \"\";\n #rootPath: string;\n #previousPath: string;\n #currentPath: string;\n #idSeed: string;\n\n idName: string;\n description: string;\n\n rootAddress: string;\n identityKey: string;\n identityAttributes: IdentityAttributes;\n\n getApiData: APIFetcher\n\n constructor(\n HDPrivateKey: HD,\n identityAttributes: IdentityAttributes = {},\n idSeed = \"\",\n ) {\n this.#idSeed = idSeed;\n if (idSeed) {\n // create a new HDPrivateKey based on the seed\n const seedHex = toHex(Hash.sha256(idSeed, \"utf8\"));\n const seedPath = Utils.getSigningPathFromHex(seedHex);\n this.#HDPrivateKey = HDPrivateKey.derive(seedPath);\n } else {\n this.#HDPrivateKey = HDPrivateKey;\n }\n\n this.idName = \"ID 1\";\n this.description = \"\";\n\n this.#rootPath = `${SIGNING_PATH_PREFIX}/0/0/0`;\n this.#previousPath = `${SIGNING_PATH_PREFIX}/0/0/0`;\n this.#currentPath = `${SIGNING_PATH_PREFIX}/0/0/1`;\n\n const rootChild = this.#HDPrivateKey.derive(this.#rootPath);\n this.rootAddress = rootChild.privKey.toPublicKey().toAddress();\n this.identityKey = this.deriveIdentityKey(this.rootAddress);\n\n // unlink the object\n const attributes = { ...identityAttributes };\n this.identityAttributes = this.parseAttributes(attributes);\n\n this.getApiData = apiFetcher(this.#BAP_SERVER, this.#BAP_TOKEN);\n }\n\n set BAP_SERVER(bapServer) {\n this.#BAP_SERVER = bapServer;\n }\n\n get BAP_SERVER(): string {\n return this.#BAP_SERVER;\n }\n\n set BAP_TOKEN(token) {\n this.#BAP_TOKEN = token;\n }\n\n get BAP_TOKEN(): string {\n return this.#BAP_TOKEN;\n }\n\n deriveIdentityKey(address: string): string {\n // base58( ripemd160 ( sha256 ( rootAddress ) ) )\n const rootAddressHash = toHex(Hash.sha256(address, \"utf8\"));\n return toBase58(Hash.ripemd160(rootAddressHash, \"hex\"));\n }\n\n /**\n * Helper function to parse identity attributes\n *\n * @param identityAttributes\n * @returns {{}}\n */\n parseAttributes(\n identityAttributes: IdentityAttributes | string,\n ): IdentityAttributes {\n if (typeof identityAttributes === \"string\") {\n return this.parseStringUrns(identityAttributes);\n }\n\n for (const key in identityAttributes) {\n if (!identityAttributes[key].value || !identityAttributes[key].nonce) {\n throw new Error(\"Invalid identity attribute\");\n }\n }\n\n return identityAttributes || {};\n }\n\n /**\n * Parse a text of urn string into identity attributes\n *\n * urn:bap:id:name:John Doe:e2c6fb4063cc04af58935737eaffc938011dff546d47b7fbb18ed346f8c4d4fa\n * urn:bap:id:birthday:1990-05-22:e61f23cbbb2284842d77965e2b0e32f0ca890b1894ca4ce652831347ee3596d9\n * urn:bap:id:over18:1:480ca17ccaacd671b28dc811332525f2f2cd594d8e8e7825de515ce5d52d30e8\n *\n * @param urnIdentityAttributes\n */\n parseStringUrns(urnIdentityAttributes: string): IdentityAttributes {\n const identityAttributes: IdentityAttributes = {};\n // avoid forEach\n\n const attributesRaw = urnIdentityAttributes\n .replace(/^\\s+/g, \"\")\n .replace(/\\r/gm, \"\")\n .split(\"\\n\");\n\n for (const line of attributesRaw) {\n // remove any whitespace from the string (trim)\n const attribute = line.replace(/^\\s+/g, \"\").replace(/\\s+$/g, \"\");\n const urn = attribute.split(\":\");\n if (\n urn[0] === \"urn\" &&\n urn[1] === \"bap\" &&\n urn[2] === \"id\" &&\n urn[3] &&\n urn[4] &&\n urn[5]\n ) {\n identityAttributes[urn[3]] = {\n value: urn[4],\n nonce: urn[5],\n };\n }\n }\n\n return identityAttributes;\n }\n\n /**\n * Returns the identity key\n *\n * @returns {*|string}\n */\n getIdentityKey(): string {\n return this.identityKey;\n }\n\n /**\n * Returns all the attributes in the identity\n *\n * @returns {*}\n */\n getAttributes(): IdentityAttributes {\n return this.identityAttributes;\n }\n\n /**\n * Get the value of the given attribute\n *\n * @param attributeName\n * @returns {{}|null}\n */\n getAttribute(attributeName: string): IdentityAttribute | null {\n if (this.identityAttributes[attributeName]) {\n return this.identityAttributes[attributeName];\n }\n\n return null;\n }\n\n /**\n * Set the value of the given attribute\n *\n * If an empty value ('' || null || false) is given, the attribute is removed from the ID\n *\n * @param attributeName string\n * @param attributeValue any\n * @returns {{}|null}\n */\n setAttribute(attributeName: string, attributeValue: string | Record<string, string>): void {\n if (!attributeValue) {\n return;\n }\n\n if (this.identityAttributes[attributeName]) {\n this.updateExistingAttribute(attributeName, attributeValue);\n } else {\n this.createNewAttribute(attributeName, attributeValue);\n }\n }\n\n private updateExistingAttribute(\n attributeName: string,\n attributeValue: string | Record<string, string>\n ): void {\n if (typeof attributeValue === 'string') {\n this.identityAttributes[attributeName].value = attributeValue;\n return;\n }\n\n this.identityAttributes[attributeName].value = attributeValue.value || '';\n if (attributeValue.nonce) {\n this.identityAttributes[attributeName].nonce = attributeValue.nonce;\n }\n }\n\n private createNewAttribute(\n attributeName: string,\n attributeValue: string | Record<string, string>\n ): void {\n if (typeof attributeValue === 'string') {\n this.addAttribute(attributeName, attributeValue);\n return;\n }\n\n this.addAttribute(\n attributeName,\n attributeValue.value || '',\n attributeValue.nonce\n );\n }\n\n /**\n * Unset the given attribute from the ID\n *\n * @param attributeName\n * @returns {{}|null}\n */\n unsetAttribute(attributeName: string): void {\n delete this.identityAttributes[attributeName];\n }\n\n /**\n * Get all attribute urn's for this id\n *\n * @returns {string}\n */\n getAttributeUrns(): string {\n let urns = \"\";\n for (const key in this.identityAttributes) {\n const urn = this.getAttributeUrn(key);\n if (urn) {\n urns += `${urn}\\n`;\n }\n }\n\n return urns;\n }\n\n /**\n * Create an return the attribute urn for the given attribute\n *\n * @param attributeName\n * @returns {string|null}\n */\n getAttributeUrn(attributeName: string): string | null {\n const attribute = this.identityAttributes[attributeName];\n if (attribute) {\n return `urn:bap:id:${attributeName}:${attribute.value}:${attribute.nonce}`;\n }\n\n return null;\n }\n\n /**\n * Add an attribute to this identity\n *\n * @param attributeName\n * @param value\n * @param nonce\n */\n addAttribute(attributeName: string, value: string, nonce = \"\"): void {\n let nonceToUse = nonce;\n if (!nonce) {\n nonceToUse = Utils.getRandomString();\n }\n\n this.identityAttributes[attributeName] = {\n value,\n nonce: nonceToUse,\n };\n }\n\n /**\n * This should be called with the last part of the signing path (/.../.../...)\n * This library assumes the first part is m/424150'/0'/0' as defined at the top of this file\n *\n * @param path The second path of the signing path in the format [0-9]{0,9}/[0-9]{0,9}/[0-9]{0,9}\n */\n set rootPath(path: string) {\n if (this.#HDPrivateKey) {\n let pathToUse = path;\n if (path.split(\"/\").length < 5) {\n pathToUse = `${SIGNING_PATH_PREFIX}${path}`;\n }\n\n if (!this.validatePath(pathToUse)) {\n throw new Error(`invalid signing path given ${pathToUse}`);\n }\n\n this.#rootPath = pathToUse;\n\n const derivedChild = this.#HDPrivateKey.derive(pathToUse);\n this.rootAddress = derivedChild.pubKey.toAddress();\n // Identity keys should be derivatives of the root address - this allows checking\n // of the creation transaction\n this.identityKey = this.deriveIdentityKey(this.rootAddress);\n\n // we also set this previousPath / currentPath to the root as we seem to be (re)setting this ID\n this.#previousPath = pathToUse;\n this.#currentPath = pathToUse;\n }\n }\n\n get rootPath(): string {\n return this.#rootPath;\n }\n\n getRootPath(): string {\n return this.#rootPath;\n }\n\n /**\n * This should be called with the last part of the signing path (/.../.../...)\n * This library assumes the first part is m/424150'/0'/0' as defined at the top of this file\n *\n * @param path The second path of the signing path in the format [0-9]{0,9}/[0-9]{0,9}/[0-9]{0,9}\n */\n set currentPath(path) {\n let pathToUse = path;\n if (path.split(\"/\").length < 5) {\n pathToUse = `${SIGNING_PATH_PREFIX}${path}`;\n }\n\n if (!this.validatePath(pathToUse)) {\n throw new Error(\"invalid signing path given\");\n }\n\n this.#previousPath = this.#currentPath;\n this.#currentPath = pathToUse;\n }\n\n get currentPath(): string {\n return this.#currentPath;\n }\n\n get previousPath(): string {\n return this.#previousPath;\n }\n\n /**\n * This can be used to break the deterministic way child keys are created to make it harder for\n * an attacker to steal the identites when the root key is compromised. This does however require\n * the seeds to be stored at all times. If the seed is lost, the identity will not be recoverable.\n */\n get idSeed(): string {\n return this.#idSeed;\n }\n\n /**\n * Increment current path to a new path\n *\n * @returns {*}\n */\n incrementPath(): void {\n this.currentPath = Utils.getNextPath(this.currentPath);\n }\n\n /**\n * Check whether the given path is a valid path for use with this class\n * The signing paths used here always have a length of 3\n *\n * @param path The last part of the signing path (example \"/0/0/1\")\n * @returns {boolean}\n */\n validatePath(path: string) {\n /* eslint-disable max-len */\n if (\n path.match(\n /\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?\\/[0-9]{1,10}'?/,\n )\n ) {\n const pathValues = path.split(\"/\");\n if (\n pathValues.length === 7 &&\n Number(pathValues[1].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[2].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[3].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[4].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[5].replace(\"'\", \"\")) <= MAX_INT &&\n Number(pathValues[6].replace(\"'\", \"\")) <= MAX_INT\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get the OP_RETURN for the initial ID transaction (signed with root address)\n *\n * @returns {[]}\n */\n getInitialIdTransaction() {\n return this.getIdTransaction(this.#rootPath);\n }\n\n /**\n * Get the OP_RETURN for the ID transaction of the current address / path\n *\n * @returns {[]}\n */\n getIdTransaction(previousPath = \"\") {\n if (this.#currentPath === this.#rootPath) {\n throw new Error(\n \"Current path equals rootPath. ID was probably not initialized properly\",\n );\n }\n\n const opReturn = [\n Buffer.from(BAP_BITCOM_ADDRESS).toString(\"hex\"),\n Buffer.from(\"ID\").toString(\"hex\"),\n Buffer.from(this.identityKey).toString(\"hex\"),\n Buffer.from(this.getCurrentAddress()).toString(\"hex\"),\n ];\n\n return this.signOpReturnWithAIP(\n opReturn,\n previousPath || this.#previousPath,\n );\n }\n\n /**\n * Get address for given path\n *\n * @param path\n * @returns {*}\n */\n getAddress(path: string): string {\n const derivedChild = this.#HDPrivateKey.derive(path);\n return derivedChild.privKey.toPublicKey().toAddress();\n }\n\n /**\n * Get current signing address\n *\n * @returns {*}\n */\n getCurrentAddress(): string {\n return this.getAddress(this.#currentPath);\n }\n\n /**\n * Get the public key for encrypting data for this identity\n */\n getEncryptionPublicKey(): string {\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const encryptionKey = HDPrivateKey.derive(ENCRYPTION_PATH).privKey;\n // @ts-ignore\n return encryptionKey.toPublicKey().toString();\n }\n\n /**\n * Get the public key for encrypting data for this identity, using a seed for the encryption\n */\n getEncryptionPublicKeyWithSeed(seed: string): string {\n const encryptionKey = this.getEncryptionPrivateKeyWithSeed(seed);\n // @ts-ignore\n return encryptionKey.toPublicKey().toString(\"hex\");\n }\n\n /**\n * Encrypt the given string data with the identity encryption key\n * @param stringData\n * @param counterPartyPublicKey Optional public key of the counterparty\n * @return string Base64\n */\n encrypt(stringData: string, counterPartyPublicKey?: string): string {\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const encryptionKey = HDPrivateKey.derive(ENCRYPTION_PATH).privKey;\n const publicKey = encryptionKey.toPublicKey();\n const pubKey = counterPartyPublicKey\n ? PublicKey.fromString(counterPartyPublicKey)\n : publicKey;\n // @ts-ignore - remove this when SDK is updated\n return toBase64(electrumEncrypt(toArray(stringData), pubKey, null));\n }\n\n /**\n * Decrypt the given ciphertext with the identity encryption key\n * @param ciphertext\n */\n decrypt(ciphertext: string, counterPartyPublicKey?: string): string {\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const encryptionKey = HDPrivateKey.derive(ENCRYPTION_PATH).privKey;\n let pubKey = undefined\n if (counterPartyPublicKey) {\n pubKey = PublicKey.fromString(counterPartyPublicKey);\n }\n return toUTF8(electrumDecrypt(toArray(ciphertext, \"base64\"), encryptionKey, pubKey));\n }\n\n /**\n * Encrypt the given string data with the identity encryption key\n * @param stringData\n * @param seed String seed\n * @param counterPartyPublicKey Optional public key of the counterparty\n * @return string Base64\n */\n encryptWithSeed(\n stringData: string,\n seed: string,\n counterPartyPublicKey?: string,\n ): string {\n const encryptionKey = this.getEncryptionPrivateKeyWithSeed(seed);\n const publicKey = encryptionKey.toPublicKey();\n const pubKey = counterPartyPublicKey\n ? PublicKey.fromString(counterPartyPublicKey)\n : publicKey;\n return toBase64(electrumEncrypt(toArray(stringData), pubKey, encryptionKey));\n }\n\n /**\n * Decrypt the given ciphertext with the identity encryption key\n * @param ciphertext\n * @param seed String seed\n // * @param counterPartyPublicKey Public key of the counterparty\n */\n decryptWithSeed(ciphertext: string, seed: string, counterPartyPublicKey?: string): string {\n const encryptionKey = this.getEncryptionPrivateKeyWithSeed(seed);\n let pubKey = undefined\n if (counterPartyPublicKey) {\n pubKey = PublicKey.fromString(counterPartyPublicKey);\n }\n return toUTF8(electrumDecrypt(toArray(ciphertext, \"base64\"), encryptionKey, pubKey));\n }\n\n private getEncryptionPrivateKeyWithSeed(seed: string) {\n const pathHex = toHex(Hash.sha256(seed, \"utf8\"));\n const path = Utils.getSigningPathFromHex(pathHex);\n\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n return HDPrivateKey.derive(path).privKey;\n }\n\n /**\n * Get an attestation string for the given urn for this identity\n *\n * @param urn\n * @returns {string}\n */\n getAttestation(urn: string) {\n const urnHash = Hash.sha256(urn, \"utf8\");\n return `bap:attest:${toHex(urnHash)}:${this.getIdentityKey()}`;\n }\n\n /**\n * Generate and return the attestation hash for the given attribute of this identity\n *\n * @param attribute Attribute name (name, email etc.)\n * @returns {string}\n */\n getAttestationHash(attribute: string) {\n const urn = this.getAttributeUrn(attribute);\n if (!urn) return null;\n\n const attestation = this.getAttestation(urn);\n const attestationHash = Hash.sha256(attestation, \"utf8\");\n\n return toHex(attestationHash);\n }\n\n /**\n * Sign a message with the current signing address of this identity\n *\n * @param message\n * @param signingPath\n * @returns {{address: string, signature: string}}\n */\n signMessage(message: string | Buffer, signingPath = \"\"): { address: string, signature: string } {\n let msg: Buffer;\n if (!(message instanceof Buffer)) {\n msg = Buffer.from(message);\n } else {\n msg = message;\n }\n\n const pathToUse = signingPath || this.#currentPath;\n const childPk = this.#HDPrivateKey.derive(pathToUse).privKey;\n const address = childPk.toAddress();\n\n // Needed to calculate the recovery factor\n const dummySig = BSM.sign(toArray(message), childPk, 'raw') as Signature;\n const h = new BigNumber(magicHash(toArray(message, \"utf8\")));\n const r = dummySig.CalculateRecoveryFactor(\n childPk.toPublicKey(),\n h,\n );\n const signature = (BSM.sign(toArray(msg), childPk, 'raw') as Signature).toCompact(\n r,\n true,\n \"base64\",\n ) as string;\n\n return { address, signature };\n }\n\n /**\n * Sign a message using a key based on the given string seed\n *\n * This works by creating a private key from the root key of this identity. It will always\n * work with the rootPath / rootKey, to be deterministic. It will not change even if the keys\n * are rotated for this ID.\n *\n * This is used in for instance deterministic login systems, that do not support BAP.\n *\n * @param message\n * @param seed {string} String seed that will be used to generate a path\n */\n signMessageWithSeed(\n message: string,\n seed: string,\n ): { address: string; signature: string } {\n const pathHex = toHex(Hash.sha256(seed, \"utf8\"));\n const path = Utils.getSigningPathFromHex(pathHex);\n\n const HDPrivateKey = this.#HDPrivateKey.derive(this.#rootPath);\n const derivedChild = HDPrivateKey.derive(path);\n const address = derivedChild.privKey.toPublicKey().toAddress();\n\n const dummySig = BSM.sign(toArray(message), derivedChild.privKey, 'raw') as Signature;\n\n const h = new BigNumber(magicHash(toArray(message, \"utf8\")));\n const r = dummySig.CalculateRecoveryFactor(\n derivedChild.privKey.toPublicKey(),\n h,\n );\n\n const signature = (BSM.sign(\n toArray(Buffer.from(message)),\n derivedChild.privKey,\n 'raw',\n ) as Signature).toCompact(r, true, \"base64\") as string;\n\n return { address, signature };\n }\n\n /**\n * Sign an op_return hex array with AIP\n * @param opReturn {array}\n * @param signingPath {string}\n * @param outputType {string}\n * @return {[]}\n */\n signOpReturnWithAIP(\n opReturn: string[],\n signingPath = \"\",\n outputType: BufferEncoding = \"hex\",\n ): string[] {\n const aipMessageBuffer = this.getAIPMessageBuffer(opReturn);\n const { address, signature } = this.signMessage(\n aipMessageBuffer,\n signingPath,\n );\n\n return opReturn.concat([\n Buffer.from(\"|\").toString(outputType),\n Buffer.from(AIP_BITCOM_ADDRESS).toString(outputType),\n Buffer.from(\"BITCOIN_ECDSA\").toString(outputType),\n Buffer.from(address).toString(outputType),\n Buffer.from(signature, \"base64\").toString(outputType),\n ]);\n }\n\n /**\n * Construct an AIP buffer from the op return data\n * @param opReturn\n * @returns {Buffer}\n */\n getAIPMessageBuffer(opReturn: string[]): Buffer {\n const buffers = [];\n if (opReturn[0].replace(\"0x\", \"\") !== \"6a\") {\n // include OP_RETURN in constructing the signature buffer\n buffers.push(Buffer.from(\"6a\", \"hex\"));\n }\n for (const op of opReturn) {\n buffers.push(Buffer.from(op.replace(\"0x\", \"\"), \"hex\"));\n }\n // add a trailing \"|\" - this is the AIP way\n buffers.push(Buffer.from(\"|\"));\n\n return Buffer.concat([...buffers] as unknown as Uint8Array[]);\n }\n\n /**\n * Get all signing keys for this identity\n */\n async getIdSigningKeys(): Promise<GetSigningKeysResponse> {\n const signingKeys = await this.getApiData<GetSigningKeysResponse>(\"/signing-keys\", {\n idKey: this.identityKey,\n });\n console.log(\"getIdSigningKeys\", signingKeys);\n\n return signingKeys;\n }\n\n /**\n * Get all attestations for the given attribute\n *\n * @param attribute\n */\n async getAttributeAttestations(attribute: string): Promise<GetAttestationResponse> {\n // This function needs to make a call to a BAP server to get all the attestations for this\n // identity for the given attribute\n const attestationHash = this.getAttestationHash(attribute);\n\n // get all BAP ATTEST records for the given attestationHash\n const attestations = await this.getApiData<GetAttestationResponse>(\"/attestation/get\", {\n hash: attestationHash,\n });\n console.log(\"getAttestations\", attribute, attestationHash, attestations);\n\n return attestations;\n }\n\n // /**\n // * Helper function to get attestation from a BAP API server\n // *\n // * @param apiUrl\n // * @param apiData\n // * @returns {Promise<any>}\n // */\n // async getApiData(apiUrl: string, apiData: any): Promise<any> {\n // \tconst url = `${this.#BAP_SERVER}${apiUrl}`;\n // \tconst response = await fetch(url, {\n // \t\tmethod: \"post\",\n // \t\theaders: {\n // \t\t\t\"Content-type\": \"application/json; charset=utf-8\",\n // \t\t\ttoken: this.#BAP_TOKEN,\n // \t\t\tformat: \"json\",\n // \t\t},\n // \t\tbody: JSON.stringify(apiData),\n // \t});\n // \treturn response.json();\n // }\n\n /**\n * Import an identity from a JSON object\n *\n * @param identity{{}}\n */\n import(identity: Identity | OldIdentity): void {\n this.idName = identity.name;\n this.description = identity.description || \"\";\n this.identityKey = identity.identityKey;\n this.#rootPath = identity.rootPath;\n this.rootAddress = identity.rootAddress;\n this.#previousPath = identity.previousPath;\n this.#currentPath = identity.currentPath;\n this.#idSeed = ('idSeed' in identity ? identity.idSeed : \"\") || \"\";\n this.identityAttributes = this.parseAttributes(identity.identityAttributes);\n }\n\n /**\n * Export this identity to a JSON object\n * @returns {{}}\n */\n export(): Identity {\n return {\n name: this.idName,\n description: this.description,\n identityKey: this.identityKey,\n rootPath: this.#rootPath,\n rootAddress: this.rootAddress,\n previousPath: this.#previousPath,\n currentPath: this.#currentPath,\n idSeed: this.#idSeed,\n identityAttributes: this.getAttributes(),\n lastIdPath: \"\",\n };\n }\n\n // New method to export a member-friendly backup, containing only the derived signing key\n exportMemberBackup(): MemberIdentity {\n const derivedKey = this.#HDPrivateKey.derive(this.#currentPath).privKey;\n return {\n name: this.idName,\n description: this.description,\n derivedPrivateKey: derivedKey.toString(),\n address: derivedKey.toPublicKey().toAddress(),\n identityAttributes: this.getAttributes(),\n };\n }\n\n // New method to derive a new member ID from the master HD key\n public newId(): MemberID {\n // Assuming incrementPath updates the internal current path\n this.incrementPath();\n const derivedKey = this.#HDPrivateKey.derive(this.#currentPath).privKey;\n return new MemberID(derivedKey, this.getAttributes());\n }\n}\n\nexport { MasterID };\n",
9
9
  "import { randomBytes } from 'node:crypto';\nimport type { PathPrefix } from \"./interface.js\";\n\nexport const Utils = {\n /**\n * Helper function for encoding strings to hex\n *\n * @param string\n * @returns {string}\n */\n hexEncode(string: string) {\n return `0x${Buffer.from(string).toString('hex')}`;\n },\n\n /**\n * Helper function for encoding strings to hex\n *\n * @param hexString string\n * @param encoding BufferEncoding\n * @returns {string}\n */\n hexDecode(hexString: string, encoding: BufferEncoding = 'utf8') {\n return Buffer.from(hexString.replace('0x', ''), 'hex').toString(encoding);\n },\n\n /**\n * Helper function to generate a random nonce\n *\n * @returns {string}\n */\n getRandomString(length = 32) {\n return randomBytes(length).toString('hex');\n },\n\n /**\n * Test whether the given string is hex\n *\n * @param value any\n * @returns {boolean}\n */\n isHex(value: string): boolean {\n if (typeof value !== 'string') {\n return false;\n }\n return /^[0-9a-fA-F]+$/.test(value);\n },\n\n /**\n * Get a signing path from a hex number\n *\n * @param hexString {string}\n * @param hardened {boolean} Whether to return a hardened path\n * @returns {string}\n */\n getSigningPathFromHex(hexString: string, hardened = true) {\n // \"m/0/0/1\"\n let signingPath = 'm';\n const signingHex = hexString.match(/.{1,8}/g);\n if (!signingHex) {\n throw new Error('Invalid hex string');\n }\n const maxNumber = 2147483648 - 1; // 0x80000000\n for (const hexNumber of signingHex) {\n let number = Number(`0x${hexNumber}`);\n if (number > maxNumber) number -= maxNumber;\n signingPath += `/${number}${(hardened ? \"'\" : '')}`;\n }\n\n return signingPath;\n },\n\n /**\n * Increment that second to last part from the given part, set the last part to 0\n *\n * @param path string\n * @returns {*}\n */\n getNextIdentityPath(path: string): PathPrefix {\n const pathValues = path.split('/');\n const secondToLastPart = pathValues[pathValues.length - 2];\n\n let hardened = false;\n if (secondToLastPart.match('\\'')) {\n hardened = true;\n }\n\n const nextPath = (Number(secondToLastPart.replace(/[^0-9]/g, '')) + 1).toString();\n pathValues[pathValues.length - 2] = nextPath + (hardened ? '\\'' : '');\n pathValues[pathValues.length - 1] = `0${hardened ? '\\'' : ''}`;\n\n return pathValues.join('/') as PathPrefix;\n },\n\n /**\n * Increment that last part of the given path\n *\n * @param path string\n * @returns {*}\n */\n getNextPath(path: string) {\n const pathValues = path.split('/');\n const lastPart = pathValues[pathValues.length - 1];\n let hardened = false;\n if (lastPart.match('\\'')) {\n hardened = true;\n }\n const nextPath = (Number(lastPart.replace(/[^0-9]/g, '')) + 1).toString();\n pathValues[pathValues.length - 1] = nextPath + (hardened ? '\\'' : '');\n return pathValues.join('/');\n },\n};\n",
10
10
  "import { BSM, type Signature, BigNumber, PrivateKey, Utils, Hash } from \"@bsv/sdk\";\n\nconst { toHex, toBase58, toArray } = Utils;\nconst { magicHash } = BSM;\nimport type { IdentityAttributes } from \"./interface\";\n\nexport interface MemberIdentity {\n name: string;\n description: string;\n derivedPrivateKey: string;\n address: string;\n identityAttributes: IdentityAttributes;\n}\n\nclass MemberID {\n private key: PrivateKey;\n public identityAttributes: IdentityAttributes;\n public address: string;\n public idName: string;\n public description: string;\n\n constructor(key: PrivateKey, identityAttributes: IdentityAttributes | string = {}) {\n this.key = key;\n // If identityAttributes is a string, parse it using parseStringUrns, otherwise use as is\n this.identityAttributes = typeof identityAttributes === 'string' ? this.parseStringUrns(identityAttributes) : identityAttributes;\n this.address = this.key.toAddress();\n this.idName = \"Member ID 1\";\n this.description = \"\";\n }\n\n // Basic message signing using the member's derived private key\n public signMessage(message: string | Buffer): { address: string; signature: string } {\n const msgBuffer = typeof message === 'string' ? Buffer.from(message) : message;\n const childPk = this.key;\n const address = childPk.toPublicKey().toString();\n // Sign using the raw message buffer directly\n const dummySig = BSM.sign(toArray(msgBuffer), childPk, 'raw') as Signature;\n const h = new BigNumber(magicHash(toArray(msgBuffer, \"utf8\")));\n const r = dummySig.CalculateRecoveryFactor(childPk.toPublicKey(), h);\n const signature = (BSM.sign(toArray(msgBuffer), childPk, 'raw') as Signature).toCompact(r, true, \"base64\") as string;\n return { address, signature };\n }\n \n // Return the member's public key\n public getPublicKey(): string {\n return this.key.toPublicKey().toString();\n }\n \n // Import the member identity from an object containing the derived private key and identity data\n public import(identity: MemberIdentity): void {\n this.idName = identity.name;\n this.description = identity.description;\n this.key = PrivateKey.fromString(identity.derivedPrivateKey);\n this.address = this.key.toAddress();\n this.identityAttributes = identity.identityAttributes;\n }\n\n static fromImport(identity: MemberIdentity): MemberID {\n const member = new MemberID(PrivateKey.fromString(identity.derivedPrivateKey));\n member.import(identity);\n return member;\n }\n\n // Export the member identity as an object containing the derived private key and identity data\n public export(): MemberIdentity {\n return {\n name: this.idName,\n description: this.description,\n derivedPrivateKey: this.key.toString(),\n address: this.address,\n identityAttributes: this.identityAttributes\n } as MemberIdentity;\n }\n \n // Helper to parse identity attributes from a string of URNs\n private parseStringUrns(urnIdentityAttributes: string): IdentityAttributes {\n const attrs: IdentityAttributes = {};\n const lines = urnIdentityAttributes.replace(/^[ \\t]+/gm, \"\").trim().split(\"\\n\");\n for (const line of lines) {\n const parts = line.split(\":\");\n if (parts.length >= 6 && parts[0] === \"urn\" && parts[1] === \"bap\" && parts[2] === \"id\") {\n attrs[parts[3]] = { value: parts[4], nonce: parts[5] };\n }\n }\n return attrs;\n }\n }\n\n export { MemberID };"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "1D3171E9D890176264756E2164756E21",
12
+ "mappings": "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",
13
+ "debugId": "2611D71C4EE78D4664756E2164756E21",
14
14
  "names": []
15
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bsv-bap",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "BAP npm module",
5
5
  "repository": {
6
6
  "type": "git",