bsv-bap 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -156,6 +156,33 @@ async function discoverIdentities(bap, checkExistsOnChain) {
156
156
  }
157
157
  ```
158
158
 
159
+ ### Wallet Rotation Semantics
160
+
161
+ The BAP ID is defined by the member key at `rootPath`, while the active wallet/signing root follows `currentPath`.
162
+
163
+ - `rootPath`: stable member key, used to derive the BAP ID
164
+ - `currentPath`: active wallet root, used for signing and wallet operations
165
+ - `incrementPath()`: rotates the wallet/signing root without changing the BAP ID
166
+
167
+ For Type 42 identities the first rotation now moves from `bap:0` to `bap:0:1`, then `bap:0:2`, and so on.
168
+
169
+ For backward compatibility, malformed numeric rotation paths created by older buggy Type 42 builds continue rotating numerically (`1` -> `2`). New identities always use the namespaced `bap:<identity>:<rotation>` format.
170
+
171
+ ```javascript
172
+ const identity = bap.newId('Professional Identity');
173
+
174
+ const stableMemberKey = identity.getMemberKey();
175
+ const activeWalletKey = identity.getWalletPubkey();
176
+
177
+ identity.incrementPath();
178
+
179
+ // Stable identity linkage
180
+ console.log(identity.getMemberKey() === stableMemberKey); // true
181
+
182
+ // Rotated wallet/signing root
183
+ console.log(identity.getWalletPubkey() === activeWalletKey); // false
184
+ ```
185
+
159
186
  ### Migration from Legacy Derivation
160
187
 
161
188
  Existing identities using the previous (pre-signing-key-derivation) format can be migrated:
@@ -230,4 +257,4 @@ Open BSV License. See [LICENSE](LICENSE) for details.
230
257
 
231
258
  ## Acknowledgments
232
259
 
233
- Created by Siggi with contributions from Attila Aros and Satchmo.
260
+ Created by Siggi with contributions from Attila Aros and Satchmo.
@@ -103,8 +103,10 @@ declare class MasterID extends BaseClass {
103
103
  */
104
104
  getIdTransaction(previousPath?: string): number[][];
105
105
  /**
106
- * Get the private key for a given path (before identity signing key derivation)
107
- * This is the "member key" for the path
106
+ * Get the path-derived private key before identity signing derivation.
107
+ *
108
+ * At rootPath this is the stable member key that defines the BAP ID.
109
+ * At currentPath this is the active wallet root used for signing/wallet operations.
108
110
  */
109
111
  private getPathDerivedKey;
110
112
  /**
@@ -113,13 +115,23 @@ declare class MasterID extends BaseClass {
113
115
  */
114
116
  private getIdentitySigningKeyForPath;
115
117
  /**
116
- * Get the member key's public key for the given path
117
- * This is the root key before signing key derivation
118
+ * Get the stable member key's public key for this identity.
119
+ * This always resolves from rootPath and must not follow currentPath rotations.
120
+ */
121
+ getMemberKey(): string;
122
+ /**
123
+ * Get the active wallet root private key for the given path.
124
+ * Defaults to currentPath, which follows key rotation.
125
+ */
126
+ getWalletRoot(path?: string): PrivateKey;
127
+ /**
128
+ * Get the active wallet root public key for the given path.
129
+ * Defaults to currentPath, which follows key rotation.
118
130
  */
119
- getMemberKey(path?: string): string;
131
+ getWalletPubkey(path?: string): string;
120
132
  /**
121
133
  * Get the legacy (pre-signing-key-derivation) address for a path
122
- * This is the address without the extra "1-bap-identity" derivation
134
+ * This is the address without the extra "1-sigma-identity" derivation
123
135
  */
124
136
  getLegacyAddress(path?: string): string;
125
137
  /**
@@ -7,13 +7,18 @@ export declare class MemberID extends BaseClass {
7
7
  description: string;
8
8
  address: string;
9
9
  identityKey: string;
10
- constructor(key: PrivateKey, identityAttributes?: IdentityAttributes);
10
+ private counter;
11
+ constructor(key: PrivateKey, identityAttributes?: IdentityAttributes, counter?: number);
11
12
  /**
12
- * Get the derived identity signing key
13
- * This is derived from the member key using the BAP protocol pattern
14
- * invoiceNumber = "1-bap-identity" (securityLevel-protocolName-keyID)
13
+ * Get the current BRC-100 wallet root key
14
+ * Derived from member key using the rotation counter
15
15
  */
16
- private getIdentitySigningKey;
16
+ getCurrentKey(): PrivateKey;
17
+ /**
18
+ * Get the signing key derived from the current wallet root
19
+ * currentKey → Type42("1-sigma-identity") → signingKey
20
+ */
21
+ getSigningKey(): PrivateKey;
17
22
  /**
18
23
  * Get the member key's public key
19
24
  * This is the root key for this member before signing key derivation
@@ -21,16 +26,35 @@ export declare class MemberID extends BaseClass {
21
26
  */
22
27
  getMemberKey(): string;
23
28
  /**
24
- * Get the legacy (pre-signing-key-derivation) address
25
- * This is the address without the extra "1-bap-identity" derivation
29
+ * Get the root address (the member key's address)
30
+ * This is the address used for identity publication and BAP ID derivation
26
31
  */
27
- getLegacyAddress(): string;
32
+ getRootAddress(): string;
28
33
  signMessage(message: number[], _signingPath?: string): {
29
34
  address: string;
30
35
  signature: string;
31
36
  };
37
+ /**
38
+ * Sign with the root key (member key directly)
39
+ * Used for identity publication and key rotation transactions
40
+ */
41
+ signMessageWithRootKey(message: number[]): {
42
+ address: string;
43
+ signature: string;
44
+ };
45
+ /**
46
+ * Sign OP_RETURN with AIP using the root key
47
+ * Used for identity publication transactions
48
+ */
49
+ signOpReturnWithAIPUsingRootKey(opReturn: number[][]): number[][];
32
50
  signOpReturnWithAIP(opReturn: number[][]): number[][];
33
51
  getPublicKey(): string;
52
+ getCounter(): number;
53
+ /**
54
+ * Increment the rotation counter
55
+ * This changes the current key and signing key
56
+ */
57
+ rotate(): void;
34
58
  import(identity: MemberIdentity): void;
35
59
  static fromMemberIdentity(identity: MemberIdentity): MemberID;
36
60
  static fromBackup(singleBackup: {
@@ -8,6 +8,6 @@ export declare const SIGNING_PATH_PREFIX = "m/424150'/0'/0'";
8
8
  export declare const ENCRYPTION_PATH = "m/424150'/2147483647'/2147483647'";
9
9
  export declare const BAP_PROTOCOL_ID: [1, string];
10
10
  export declare const BAP_KEY_ID = "identity";
11
- export declare const BAP_INVOICE_NUMBER = "1-bap-identity";
11
+ export declare const BAP_INVOICE_NUMBER = "1-sigma-identity";
12
12
  export declare const FRIEND_SECURITY_LEVEL = 2;
13
13
  export declare const FRIEND_PROTOCOL = "friend";
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{BSM as A,BigNumber as Bj,ECIES as Ej,HD as Hj,OP as l,Signature as Tj,PrivateKey as Nj}from"@bsv/sdk";import{Utils as Sj}from"@bsv/sdk";var a=async(j,J,$,q)=>{let z=`${$}${j}`;return(await fetch(z,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify(J)})).json()},E=(j,J)=>async($,q)=>{return a($,q,j,J)};import{Utils as e}from"@bsv/sdk";var{toHex:c,toArray:b}=e,f="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",h=c(b(f)),_="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",gj=c(b(_)),H="https://api.sigmaidentity.com/v1",F=2147483647,M="m/424150'/0'/0'",Y=`m/424150'/${F}'/${F}'`;var R="1-bap-identity",p=2,P="friend";import{Utils as xj,ECIES as _j,Hash as V,PublicKey as N,HD as Rj}from"@bsv/sdk";import{Hash as o,PublicKey as t,Utils as jj}from"@bsv/sdk";var{toHex:Jj,toBase58:$j}=jj;function T(j){let J=Jj(o.sha256(j,"utf8"));return $j(o.ripemd160(J,"hex"))}function qj(j){let J=t.fromString(j);return T(J.toAddress())}var X={getRandomBytes(j=32){if(typeof globalThis<"u"&&globalThis.crypto&&globalThis.crypto.getRandomValues){let J=new Uint8Array(j);return globalThis.crypto.getRandomValues(J),J}throw Error("Secure random number generation not available. crypto.getRandomValues() is required for cryptographic operations. This environment may not be suitable for secure key generation.")},getRandomString(j=32){let J=this.getRandomBytes(j);return Array.from(J,($)=>$.toString(16).padStart(2,"0")).join("")},getSigningPathFromHex(j,J=!0){let $="m",q=j.match(/.{1,8}/g);if(!q)throw Error("Invalid hex string");let z=2147483647;for(let Q of q){let W=Number(`0x${Q}`);if(W>z)W-=z;$+=`/${W}${J?"'":""}`}return $},getNextIdentityPath(j){let J=j.split("/"),$=J[J.length-2],q=!1;if($.match("'"))q=!0;let z=(Number($.replace(/[^0-9]/g,""))+1).toString();return J[J.length-2]=z+(q?"'":""),J[J.length-1]=`0${q?"'":""}`,J.join("/")},getNextPath(j){let J=j.split("/"),$=J[J.length-1],q=!1;if($.match("'"))q=!0;let z=(Number($.replace(/[^0-9]/g,""))+1).toString();return J[J.length-1]=z+(q?"'":""),J.join("/")}};import{PublicKey as Xj,PrivateKey as v,Hash as Fj,Utils as fj,ECIES as Cj}from"@bsv/sdk";import{ECIES as zj,Utils as Qj,OP as u,PublicKey as n,BSM as D,BigNumber as Zj}from"@bsv/sdk";var{toArray:U,toUTF8:Wj,toBase64:wj}=Qj,{magicHash:Lj}=D,{electrumDecrypt:Yj,electrumEncrypt:Gj}=zj;class B{identityAttributes={};signWithBSM(j,J){let $=J.toPublicKey().toAddress(),q=D.sign(j,J,"raw"),z=new Zj(Lj(j)),Q=q.CalculateRecoveryFactor(J.toPublicKey(),z),W=D.sign(j,J,"raw").toCompact(Q,!0,"base64");return{address:$,signature:W}}encrypt(j,J){let{privKey:$,pubKey:q}=this.getEncryptionKey(),z=J?n.fromString(J):q;return wj(Gj(U(j),z,$))}decrypt(j,J){let{privKey:$}=this.getEncryptionKey(),q;if(J)q=n.fromString(J);return Wj(Yj(U(j,"base64"),$,q))}signOpReturnWithAIP(j,J){let $=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage($.flat(),J);return this.formatAIPOutput($,q,z)}getAttributes(){return this.identityAttributes}getAttribute(j){if(this.identityAttributes[j])return this.identityAttributes[j];return null}setAttribute(j,J){if(!J)return;if(this.identityAttributes[j])this.updateExistingAttribute(j,J);else this.createNewAttribute(j,J)}unsetAttribute(j){delete this.identityAttributes[j]}addAttribute(j,J,$=""){let q=$;if(!$)q=X.getRandomString();this.identityAttributes[j]={value:J,nonce:q}}getAttributeUrns(){let j="";for(let J in this.identityAttributes){let $=this.getAttributeUrn(J);if($)j+=`${$}
2
+ import{BSM as A,BigNumber as Bj,ECIES as Ej,HD as Tj,OP as l,Signature as Hj,PrivateKey as Nj}from"@bsv/sdk";import{Utils as Sj}from"@bsv/sdk";var a=async(j,J,$,q)=>{let z=`${$}${j}`;return(await fetch(z,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:q,format:"json"},body:JSON.stringify(J)})).json()},E=(j,J)=>async($,q)=>{return a($,q,j,J)};import{Utils as e}from"@bsv/sdk";var{toHex:c,toArray:b}=e,C="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",h=c(b(C)),R="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",gj=c(b(R)),T="https://api.sigmaidentity.com/v1",F=2147483647,M="m/424150'/0'/0'",Y=`m/424150'/${F}'/${F}'`;var k="1-sigma-identity",p=2,P="friend";import{Utils as _j,ECIES as xj,Hash as O,PublicKey as N,HD as Rj}from"@bsv/sdk";import{Hash as o,PublicKey as t,Utils as jj}from"@bsv/sdk";var{toHex:Jj,toBase58:$j}=jj;function H(j){let J=Jj(o.sha256(j,"utf8"));return $j(o.ripemd160(J,"hex"))}function qj(j){let J=t.fromString(j);return H(J.toAddress())}var X={getRandomBytes(j=32){if(typeof globalThis!=="undefined"&&globalThis.crypto&&globalThis.crypto.getRandomValues){let J=new Uint8Array(j);return globalThis.crypto.getRandomValues(J),J}throw new Error("Secure random number generation not available. crypto.getRandomValues() is required for cryptographic operations. This environment may not be suitable for secure key generation.")},getRandomString(j=32){let J=this.getRandomBytes(j);return Array.from(J,($)=>$.toString(16).padStart(2,"0")).join("")},getSigningPathFromHex(j,J=!0){let $="m",q=j.match(/.{1,8}/g);if(!q)throw new Error("Invalid hex string");let z=2147483647;for(let Q of q){let W=Number(`0x${Q}`);if(W>z)W-=z;$+=`/${W}${J?"'":""}`}return $},getNextIdentityPath(j){let J=j.split("/"),$=J[J.length-2],q=!1;if($.match("'"))q=!0;let z=(Number($.replace(/[^0-9]/g,""))+1).toString();return J[J.length-2]=z+(q?"'":""),J[J.length-1]=`0${q?"'":""}`,J.join("/")},getNextPath(j){let J=j.match(/^bap:(\d+)(?::(\d+))?$/);if(J){let W=J[1],w=J[2];if(w===void 0)return`bap:${W}:1`;return`bap:${W}:${Number(w)+1}`}if(/^\d+$/.test(j))return(Number(j)+1).toString();if(!j.includes("/"))throw new Error(`Unsupported non-BIP32 path: ${j}`);let $=j.split("/"),q=$[$.length-1],z=!1;if(q.match("'"))z=!0;let Q=(Number(q.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=Q+(z?"'":""),$.join("/")}};import{PublicKey as Xj,PrivateKey as v,Hash as Fj,Utils as Cj,ECIES as fj}from"@bsv/sdk";import{ECIES as zj,Utils as Qj,OP as u,PublicKey as n,BSM as D,BigNumber as Zj}from"@bsv/sdk";var{toArray:U,toUTF8:Wj,toBase64:wj}=Qj,{magicHash:Lj}=D,{electrumDecrypt:Yj,electrumEncrypt:Gj}=zj;class B{identityAttributes={};signWithBSM(j,J){let $=J.toPublicKey().toAddress(),q=D.sign(j,J,"raw"),z=new Zj(Lj(j)),Q=q.CalculateRecoveryFactor(J.toPublicKey(),z),W=D.sign(j,J,"raw").toCompact(Q,!0,"base64");return{address:$,signature:W}}encrypt(j,J){let{privKey:$,pubKey:q}=this.getEncryptionKey(),z=J?n.fromString(J):q;return wj(Gj(U(j),z,$))}decrypt(j,J){let{privKey:$}=this.getEncryptionKey(),q;if(J)q=n.fromString(J);return Wj(Yj(U(j,"base64"),$,q))}signOpReturnWithAIP(j,J){let $=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage($.flat(),J);return this.formatAIPOutput($,q,z)}getAttributes(){return this.identityAttributes}getAttribute(j){if(this.identityAttributes[j])return this.identityAttributes[j];return null}setAttribute(j,J){if(!J)return;if(this.identityAttributes[j])this.updateExistingAttribute(j,J);else this.createNewAttribute(j,J)}unsetAttribute(j){delete this.identityAttributes[j]}addAttribute(j,J,$=""){let q=$;if(!$)q=X.getRandomString();this.identityAttributes[j]={value:J,nonce:q}}getAttributeUrns(){let j="";for(let J in this.identityAttributes){let $=this.getAttributeUrn(J);if($)j+=`${$}
3
3
  `}return j}getAttributeUrn(j){let J=this.identityAttributes[j];if(J)return`urn:bap:id:${j}:${J.value}:${J.nonce}`;return null}parseStringUrns(j){let J={},$=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
4
- `);for(let q of $){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])J[Q[3]]={value:Q[4],nonce:Q[5]}}return J}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let J in j)if(!j[J].value||!j[J].nonce)throw Error("Invalid identity attribute");return j||{}}updateExistingAttribute(j,J){if(typeof J==="string"){this.identityAttributes[j].value=J;return}if(this.identityAttributes[j].value=J.value||"",J.nonce)this.identityAttributes[j].nonce=J.nonce}createNewAttribute(j,J){if(typeof J==="string"){this.addAttribute(j,J);return}this.addAttribute(j,J.value||"",J.nonce)}getAIPMessageBuffer(j,J){let $=j.findIndex((z)=>z[0]===u.OP_RETURN),q=[];if($===-1)q.push([u.OP_RETURN]),$=0;if(J)for(let z of J)q.push(j[$+z]);else for(let z of j)q.push(z);return q}formatAIPOutput(j,J,$){let q=[U("|"),U(_),U("BITCOIN_ECDSA"),U(J),U($,"base64")];return[...j,...q]}}var{toArray:d,toUTF8:Uj,toBase64:Mj,toHex:kj}=fj,{electrumDecrypt:Vj,electrumEncrypt:Oj}=Cj;class k extends B{key;idName;description;address;identityKey;constructor(j,J={}){super();this.key=j,this.address=this.getIdentitySigningKey().toPublicKey().toAddress(),this.idName="Member ID 1",this.description="",this.identityKey="",this.identityAttributes=this.parseAttributes(J)}getIdentitySigningKey(){return this.key.deriveChild(this.key.toPublicKey(),R)}getMemberKey(){return this.key.toPublicKey().toString()}getLegacyAddress(){return this.key.toPublicKey().toAddress()}signMessage(j,J){let $=this.getIdentitySigningKey();return this.signWithBSM(j,$)}signOpReturnWithAIP(j){let J=this.getAIPMessageBuffer(j),{address:$,signature:q}=this.signMessage(J.flat());return this.formatAIPOutput(J,$,q)}getPublicKey(){return this.getIdentitySigningKey().toPublicKey().toString()}import(j){this.idName=j.name,this.description=j.description,this.key=v.fromWif(j.derivedPrivateKey),this.address=this.getIdentitySigningKey().toPublicKey().toAddress(),this.identityAttributes=j.identityAttributes||{},this.identityKey=j.identityKey}static fromMemberIdentity(j){let J=new k(v.fromWif(j.derivedPrivateKey));return J.import(j),J}static fromBackup(j){let J=new k(v.fromWif(j.wif)),$=JSON.parse(J.decrypt(j.id));return J.import($),J}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toWif(),address:this.address,identityAttributes:this.getAttributes(),identityKey:this.identityKey}}getEncryptionKey(){return{privKey:this.key.deriveChild(this.key.toPublicKey(),Y),pubKey:this.key.deriveChild(this.key.toPublicKey(),Y).toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPrivateKeyWithSeed(j){let J=kj(Fj.sha256(j,"utf8")),$=`${p}-${P}-${J}`;return this.key.deriveChild(this.key.toPublicKey(),$)}getEncryptionKeyWithSeed(j){let J=this.getEncryptionPrivateKeyWithSeed(j);return{privKey:J,pubKey:J.toPublicKey()}}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z=q.toPublicKey(),Q=this.key.toPublicKey().constructor,W=$?Q.fromString($):z;return Mj(Oj(d(j),W,q))}decryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z;if($)z=Xj.fromString($);return Uj(Vj(d(j,"base64"),q,z))}exportForBackup(j){let J=this.export(),$=this.encrypt(JSON.stringify(J));return{wif:this.key.toWif(),id:$,...j&&{label:j},createdAt:new Date().toISOString()}}}var{toArray:L,toHex:O,toBase58:aj,toUTF8:y,toBase64:I}=xj,{electrumDecrypt:s,electrumEncrypt:g}=_j;class C extends B{#J;#j;#q;#Q=H;#W="";#$;#Z;#z;#w;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,J={},$=""){super();if(j instanceof Rj)if(this.#q=!1,$){let z=O(V.sha256($,"utf8")),Q=X.getSigningPathFromHex(z);this.#J=j.derive(Q)}else this.#J=j;else if(this.#q=!0,this.#j=j.rootPk,$){let z=O(V.sha256($,"utf8"));this.#j=this.#j.deriveChild(this.#j.toPublicKey(),z)}if(this.#w=$,this.idName="ID 1",this.description="",this.#$=`${M}/0/0/0`,this.#Z=`${M}/0/0/0`,this.#z=`${M}/0/0/1`,this.#q){if(!this.#j)throw Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#$);this.rootAddress=z.toPublicKey().toAddress()}else{if(!this.#J)throw Error("HD private key not initialized");let z=this.#J.derive(this.#$);this.rootAddress=z.privKey.toPublicKey().toAddress()}this.identityKey=this.deriveIdentityKey(this.rootAddress);let q={...J};this.identityAttributes=this.parseAttributes(q),this.getApiData=E(this.#Q,this.#W)}set BAP_SERVER(j){this.#Q=j}get BAP_SERVER(){return this.#Q}set BAP_TOKEN(j){this.#W=j}get BAP_TOKEN(){return this.#W}deriveIdentityKey(j){return T(j)}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let J in j)if(!j[J].value||!j[J].nonce)throw Error("Invalid identity attribute");return j||{}}parseStringUrns(j){let J={},$=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
5
- `);for(let q of $){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])J[Q[3]]={value:Q[4],nonce:Q[5]}}return J}getIdentityKey(){return this.identityKey}set rootPath(j){if(this.#q){if(this.#$=j,!this.#j)throw Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),j);this.rootAddress=J.toPublicKey().toAddress(),this.#Z=j,this.#z=j}else{let J=j;if(j.split("/").length<5)J=`${M}${j}`;if(!this.validatePath(J))throw Error(`invalid signing path given ${J}`);if(this.#$=J,!this.#J)throw Error("HD private key not initialized");let $=this.#J.derive(J);this.rootAddress=$.pubKey.toAddress(),this.#Z=J,this.#z=J}this.identityKey=this.deriveIdentityKey(this.rootAddress)}get rootPath(){return this.#$}getRootPath(){return this.#$}set currentPath(j){if(this.#q)this.#Z=this.#z,this.#z=j;else{let J=j;if(j.split("/").length<5)J=`${M}${j}`;if(!this.validatePath(J))throw Error("invalid signing path given");this.#Z=this.#z,this.#z=J}}get currentPath(){return this.#z}get previousPath(){return this.#Z}get idSeed(){return this.#w}incrementPath(){this.currentPath=X.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=j.split("/");if(J.length===7&&Number(J[1].replace("'",""))<=F&&Number(J[2].replace("'",""))<=F&&Number(J[3].replace("'",""))<=F&&Number(J[4].replace("'",""))<=F&&Number(J[5].replace("'",""))<=F&&Number(J[6].replace("'",""))<=F)return!0}return!1}getInitialIdTransaction(){return this.getIdTransaction(this.#$)}getIdTransaction(j=""){if(this.#z===this.#$)throw Error("Current path equals rootPath. ID was probably not initialized properly");let J=[L(f),L("ID"),L(this.identityKey),L(this.getCurrentAddress())];return this.signOpReturnWithAIP(J,j||this.#Z)}getPathDerivedKey(j){if(this.#q){if(!this.#j)throw Error("Master private key not initialized");return this.#j.deriveChild(this.#j.toPublicKey(),j)}if(!this.#J)throw Error("HD private key not initialized");return this.#J.derive(j).privKey}getIdentitySigningKeyForPath(j){let J=this.getPathDerivedKey(j);return J.deriveChild(J.toPublicKey(),R)}getMemberKey(j){let J=j||this.#z;return this.getPathDerivedKey(J).toPublicKey().toString()}getLegacyAddress(j){let J=j||this.#z;return this.getPathDerivedKey(J).toPublicKey().toAddress()}needsRotation(j){let J=j||this.rootAddress,$=this.getLegacyAddress(this.#$);return J===$}getLegacyRotationTransaction(){let j=this.getAddress(this.#$),J=[L(f),L("ID"),L(this.identityKey),L(j)],$=this.getAIPMessageBuffer(J),q=this.getPathDerivedKey(this.#$),{address:z,signature:Q}=this.signWithBSM($.flat(),q);return this.formatAIPOutput(J,z,Q)}getAddress(j){return this.getIdentitySigningKeyForPath(j).toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionKey(){if(this.#q){if(!this.#j)throw Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),this.#$),q=$.deriveChild($.toPublicKey(),Y);return{privKey:q,pubKey:q.toPublicKey()}}if(!this.#J)throw Error("HD private key not initialized");let J=this.#J.derive(this.#$).derive(Y).privKey;return{privKey:J,pubKey:J.toPublicKey()}}getEncryptionKeyType42(){if(this.#q)return this.getEncryptionKey();if(!this.#J)throw Error("HD private key not initialized");let j=this.#J.derive(this.#$),J=j.privKey.deriveChild(j.toPublic().pubKey,Y);return{privKey:J,pubKey:J.toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encrypt(j,J){let{privKey:$,pubKey:q}=this.getEncryptionKey(),z=J?N.fromString(J):q;return I(g(L(j),z,$))}decrypt(j,J){let{privKey:$}=this.getEncryptionKey(),q;if(J)q=N.fromString(J);return y(s(L(j,"base64"),$,q))}encryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z=q.toPublicKey(),Q=$?N.fromString($):z;return I(g(L(j),Q,q))}decryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z;if($)z=N.fromString($);return y(s(L(j,"base64"),q,z))}getEncryptionPrivateKeyWithSeed(j){let J=O(V.sha256(j,"utf8"));if(this.#q){if(!this.#j)throw Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#$);return z.deriveChild(z.toPublicKey(),J)}if(!this.#J)throw Error("HD private key not initialized");let $=X.getSigningPathFromHex(J);return this.#J.derive(this.#$).derive($).privKey}getAttestation(j){let J=V.sha256(j,"utf8");return`bap:attest:${O(J)}:${this.getIdentityKey()}`}getAttestationHash(j){let J=this.getAttributeUrn(j);if(!J)return null;let $=this.getAttestation(J),q=V.sha256($,"utf8");return O(q)}signMessage(j,J){let $=J||this.#z,q=this.getIdentitySigningKeyForPath($);return this.signWithBSM(j,q)}signMessageWithSeed(j,J){let $=O(V.sha256(J,"utf8")),q;if(this.#q){if(!this.#j)throw Error("Master private key not initialized");let Q=this.#j.deriveChild(this.#j.toPublicKey(),this.#$);q=Q.deriveChild(Q.toPublicKey(),$)}else{if(!this.#J)throw Error("HD private key not initialized");let Q=X.getSigningPathFromHex($);q=this.#J.derive(this.#$).derive(Q).privKey}let z=q.deriveChild(q.toPublicKey(),R);return this.signWithBSM(L(j,"utf8"),z)}signOpReturnWithAIP(j,J=""){let $=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage($.flat(),J);return this.formatAIPOutput(j,q,z)}async getIdSigningKeys(){let j=await this.getApiData("/signing-keys",{idKey:this.identityKey});return console.log("getIdSigningKeys",j),j}async getAttributeAttestations(j){let J=this.getAttestationHash(j),$=await this.getApiData("/attestation/get",{hash:J});return console.log("getAttestations",j,J,$),$}import(j){this.idName=j.name,this.description=j.description||"",this.identityKey=j.identityKey,this.#$=j.rootPath,this.rootAddress=j.rootAddress,this.#Z=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.#Z,currentPath:this.#z,idSeed:this.#w,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.getPathDerivedKey(this.#z),J=this.getIdentitySigningKeyForPath(this.#z);return{name:this.idName,description:this.description,derivedPrivateKey:j.toWif(),address:J.toPublicKey().toAddress(),identityAttributes:this.getAttributes(),identityKey:this.identityKey}}newId(){this.incrementPath();let j=this.getPathDerivedKey(this.#z);return new k(j)}exportMember(){let j=this.exportMemberBackup(),J=this.getPathDerivedKey(this.#z),$=I(g(L(JSON.stringify(j)),J.toPublicKey()));return{wif:j.derivedPrivateKey,encryptedData:$}}}var{toArray:Z,toUTF8:x,toBase64:K,toHex:S}=Sj,{electrumEncrypt:i,electrumDecrypt:r}=Ej;class Dj{#J;#j;#q;#Q={};#W=H;#$="";#Z="";#z=0;getApiData;constructor(j,J="",$=""){if(!j)throw Error("No key source given");if(typeof j==="string")this.#J=Hj.fromString(j),this.#q=!1;else this.#j=Nj.fromWif(j.rootPk),this.#q=!0;if(J)this.#$=J;if($)this.#W=$;this.getApiData=E(this.#W,this.#$)}get lastIdPath(){return this.#Z}getPublicKey(j=""){if(this.#q){if(!this.#j)throw Error("Master private key not initialized");if(j)return this.#j.deriveChild(this.#j.toPublicKey(),j).toPublicKey().toString();return this.#j.toPublicKey().toString()}if(!this.#J)throw Error("HD private key not initialized");if(j)return this.#J.derive(j).pubKey.toString();return this.#J.pubKey.toString()}getHdPublicKey(j=""){if(this.#q)throw Error("HD public keys are not available in Type 42 mode");if(!this.#J)throw Error("HD private key not initialized");if(j)return this.#J.derive(j).toPublic().toString();return this.#J.toPublic().toString()}set BAP_SERVER(j){this.#W=j;for(let J in this.#Q)this.#Q[J].BAP_SERVER=j}get BAP_SERVER(){return this.#W}set BAP_TOKEN(j){this.#$=j;for(let J in this.#Q)this.#Q[J].BAP_TOKEN=j}get BAP_TOKEN(){return this.#$}checkIdBelongs(j){let J;if(this.#q){if(!this.#j)throw Error("Master private key not initialized");J=this.#j.deriveChild(this.#j.toPublicKey(),j.rootPath).toPublicKey().toAddress()}else{if(!this.#J)throw Error("HD private key not initialized");J=this.#J.derive(j.rootPath).pubKey.toAddress()}if(J!==j.rootAddress)throw Error("ID does not belong to this private key");return!0}listIds(){return Object.keys(this.#Q)}newId(j,J,$={},q=""){let z,Q,W;if(typeof j==="object"||j===void 0||typeof j==="string"&&j.startsWith("/"))Q=typeof j==="string"?j:void 0,W=typeof j==="object"?j:typeof J==="object"?J:{},z="Default Identity";else z=j,Q=typeof J==="string"?J:void 0,W=typeof J==="object"?J:$;let w;if(Q)w=Q;else if(this.#q)w=`bap:${this.#z}`,this.#z++;else w=this.getNextValidPath();let G;if(this.#q){if(!this.#j)throw Error("Type 42 parameters not initialized");G=new C({rootPk:this.#j},W,q)}else{if(!this.#J)throw Error("HD private key not initialized");G=new C(this.#J,W,q)}if(G.BAP_SERVER=this.#W,G.BAP_TOKEN=this.#$,G.idName=z,G.rootPath=w,this.#q)G.currentPath=w;else G.currentPath=X.getNextPath(w);let m=G.getIdentityKey();return this.#Q[m]=G,this.#Z=w,this.#Q[m]}removeId(j){delete this.#Q[j]}getNextValidPath(){if(this.#Z)return X.getNextIdentityPath(this.#Z);return`/0'/${Object.keys(this.#Q).length}'/0'`}newIdWithCounter(j,J=`Identity ${j}`){if(!this.#q)throw Error("newIdWithCounter only works in Type 42 mode");let $=`bap:${j}`;return this.newId(J,$)}getId(j){return this.#Q[j]||null}setId(j){this.checkIdBelongs(j),this.#Q[j.getIdentityKey()]=j}importIds(j,J=!0){if(J&&typeof j==="string"){this.importEncryptedIds(j);return}let $=j;if(!$.lastIdPath)throw Error("ID cannot be imported as it is not complete");if(!$.ids)throw Error(`ID data is not in the correct format: ${j}`);let q=j.lastIdPath;for(let z of $.ids){if(!z.identityKey||!z.identityAttributes||!z.rootAddress)throw Error("ID cannot be imported as it is not complete");let Q;if(this.#q){if(!this.#j)throw Error("Type 42 parameters not initialized");Q=new C({rootPk:this.#j},{},z.idSeed)}else{if(!this.#J)throw Error("HD private key not initialized");Q=new C(this.#J,{},z.idSeed)}if(Q.BAP_SERVER=this.#W,Q.BAP_TOKEN=this.#$,Q.import(z),q==="")q=Q.currentPath;if(this.checkIdBelongs(Q),this.#Q[Q.getIdentityKey()]=Q,this.#q&&Q.rootPath.startsWith("bap:")){let W=Q.rootPath.split(":");if(W.length>=2){let w=Number.parseInt(W[1],10);if(!Number.isNaN(w))this.#z=Math.max(this.#z,w+1)}}}this.#Z=q}importEncryptedIds(j){let J=this.decrypt(j),$=JSON.parse(J);if(Array.isArray($)){console.log(`Importing old format:
6
- `,$),this.importOldIds($);return}if(typeof $!=="object")throw Error("decrypted, but found unrecognized identities format");this.importIds($,!1)}importOldIds(j){for(let J of j){let $;if(this.#q){if(!this.#j)throw Error("Type 42 parameters not initialized");$=new C({rootPk:this.#j},{},J.idSeed??"")}else{if(!this.#J)throw Error("HD private key not initialized");$=new C(this.#J,{},J.idSeed??"")}$.BAP_SERVER=this.#W,$.BAP_TOKEN=this.#$,$.import(J),this.checkIdBelongs($),this.#Q[$.getIdentityKey()]=$,this.#Z=$.currentPath}}exportIds(j,J=!0){let $={lastIdPath:this.#Z,ids:[]},q=j||Object.keys(this.#Q);for(let z of q){if(!this.#Q[z])throw Error(`Identity ${z} not found`);$.ids.push(this.#Q[z].export())}if(J)return this.encrypt(JSON.stringify($));return $}exportId(j,J=!0){let $={lastIdPath:this.#Z,ids:[]};if($.ids.push(this.#Q[j].export()),J)return this.encrypt(JSON.stringify($));return $}encrypt(j){if(this.#q){if(!this.#j)throw Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),Y);return K(i(Z(j),$.toPublicKey(),null))}if(!this.#J)throw Error("HD private key not initialized");let J=this.#J.derive(Y);return K(i(Z(j),J.pubKey,null))}decrypt(j){if(this.#q){if(!this.#j)throw Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),Y);return x(r(Z(j,"base64"),$))}if(!this.#J)throw Error("HD private key not initialized");let J=this.#J.derive(Y);return x(r(Z(j,"base64"),J.privKey))}signAttestationWithAIP(j,J,$=0,q=""){let z=this.getId(J);if(!z)throw Error("Could not find identity to attest with");let Q=this.getAttestationBuffer(j,$,q),{address:W,signature:w}=z.signMessage(Q);return this.createAttestationTransaction(j,$,W,w,q)}verifyAttestationWithAIP(j){if(!j.every((q)=>Array.isArray(q))||j[0][0]!==l.OP_RETURN||S(j[1])!==h)throw Error("Not a valid BAP transaction");let J=S(j[7])==="44415441"?5:0,$={type:x(j[2]),hash:S(j[3]),sequence:x(j[4]),signingProtocol:x(j[7+J]),signingAddress:x(j[8+J]),signature:K(j[9+J])};if(J&&j[3]===j[8])$.data=S(j[9]);console.log({attestation:$});try{let q=[];for(let z=0;z<6+J;z++)q.push(j[z]);$.verified=this.verifySignature(q.flat(),$.signingAddress,$.signature)}catch{$.verified=!1}return $}createAttestationTransaction(j,J,$,q,z=""){let Q=[[l.OP_RETURN],Z(f),Z("ATTEST"),Z(j),Z(`${J}`),Z("|")];if(z)Q.push(Z(f),Z("DATA"),Z(j),Z(z),Z("|"));return Q.push(Z(_),Z("BITCOIN_ECDSA"),Z($),Z(q,"base64")),console.log({elements:Q}),Q}getAttestationBuffer(j,J=0,$=""){let q=[[l.OP_RETURN],Z(f),Z("ATTEST"),Z(j),Z(`${J}`),Z("|")];if($)q.push(Z(f),Z("DATA"),Z(j),Z($),Z("|"));return q.flat()}verifySignature(j,J,$){let q;if(Array.isArray(j))q=j;else if(Buffer.isBuffer(j))q=[...j];else q=Z(j,"utf8");let z=Tj.fromCompact($,"base64"),Q;for(let W=0;W<4;W++)try{if(Q=z.RecoverPublicKey(W,new Bj(A.magicHash(q))),A.verify(q,z,Q)&&Q.toAddress()===J)return!0}catch{}return!1}async verifyChallengeSignature(j,J,$,q){if(!this.verifySignature($,J,q))return!1;try{let Q=await this.getApiData("/attestation/valid",{idKey:j,address:J,challenge:$,signature:q});if(Q?.status==="success"&&Q?.result?.valid===!0)return!0;return!1}catch(Q){return console.error("API call failed:",Q),!1}}async isValidAttestationTransaction(j){if(this.verifyAttestationWithAIP(j))return this.getApiData("/attestation/valid",{tx:j});return!1}async getIdentityFromAddress(j){return this.getApiData("/identity/validByAddress",{address:j})}async getIdentity(j){return this.getApiData("/identity/get",{idKey:j})}async getAttestationsForHash(j){return this.getApiData("/attestations",{hash:j})}exportForBackup(j,J,$){let z={ids:this.exportIds(),...j&&{label:j},createdAt:new Date().toISOString()};if(this.#q){if(!this.#j)throw Error("Type 42 parameters not initialized");return{...z,rootPk:this.#j.toWif()}}if(!this.#J)throw Error("HD private key not initialized");return{...z,xprv:J||this.#J.toString(),mnemonic:$||""}}exportMemberForBackup(j,J){let $=this.#Q[j];if(!$)throw Error(`Identity ${j} not found`);let q=$.exportMember();return{wif:q.wif,id:q.encryptedData,...J&&{label:J},createdAt:new Date().toISOString()}}}export{qj as bapIdFromPubkey,T as bapIdFromAddress,k as MemberID,C as MasterID,Dj as BAP};
4
+ `);for(let q of $){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])J[Q[3]]={value:Q[4],nonce:Q[5]}}return J}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let J in j)if(!j[J].value||!j[J].nonce)throw new Error("Invalid identity attribute");return j||{}}updateExistingAttribute(j,J){if(typeof J==="string"){this.identityAttributes[j].value=J;return}if(this.identityAttributes[j].value=J.value||"",J.nonce)this.identityAttributes[j].nonce=J.nonce}createNewAttribute(j,J){if(typeof J==="string"){this.addAttribute(j,J);return}this.addAttribute(j,J.value||"",J.nonce)}getAIPMessageBuffer(j,J){let $=j.findIndex((z)=>z[0]===u.OP_RETURN),q=[];if($===-1)q.push([u.OP_RETURN]),$=0;if(J)for(let z of J)q.push(j[$+z]);else for(let z of j)q.push(z);return q}formatAIPOutput(j,J,$){let q=[U("|"),U(R),U("BITCOIN_ECDSA"),U(J),U($,"base64")];return[...j,...q]}}var{toArray:d,toUTF8:Uj,toBase64:Mj,toHex:kj}=Cj,{electrumDecrypt:Vj,electrumEncrypt:Oj}=fj;class V extends B{key;idName;description;address;identityKey;counter;constructor(j,J={},$=0){super();this.key=j,this.counter=$,this.address=this.getSigningKey().toPublicKey().toAddress(),this.idName="Member ID 1",this.description="",this.identityKey="",this.identityAttributes=this.parseAttributes(J)}getCurrentKey(){return this.key.deriveChild(this.key.toPublicKey(),`bap:${this.counter}`)}getSigningKey(){let j=this.getCurrentKey();return j.deriveChild(j.toPublicKey(),k)}getMemberKey(){return this.key.toPublicKey().toString()}getRootAddress(){return this.key.toPublicKey().toAddress()}signMessage(j,J){return this.signWithBSM(j,this.getSigningKey())}signMessageWithRootKey(j){return this.signWithBSM(j,this.key)}signOpReturnWithAIPUsingRootKey(j){let J=this.getAIPMessageBuffer(j),{address:$,signature:q}=this.signMessageWithRootKey(J.flat());return this.formatAIPOutput(J,$,q)}signOpReturnWithAIP(j){let J=this.getAIPMessageBuffer(j),{address:$,signature:q}=this.signMessage(J.flat());return this.formatAIPOutput(J,$,q)}getPublicKey(){return this.getSigningKey().toPublicKey().toString()}getCounter(){return this.counter}rotate(){this.counter++,this.address=this.getSigningKey().toPublicKey().toAddress()}import(j){this.idName=j.name,this.description=j.description,this.key=v.fromWif(j.derivedPrivateKey),this.counter=j.counter??0,this.address=this.getSigningKey().toPublicKey().toAddress(),this.identityAttributes=j.identityAttributes||{},this.identityKey=j.identityKey}static fromMemberIdentity(j){let J=new V(v.fromWif(j.derivedPrivateKey),{},j.counter??0);return J.import(j),J}static fromBackup(j){let J=new V(v.fromWif(j.wif)),$=JSON.parse(J.decrypt(j.id));return J.import($),J}export(){return{name:this.idName,description:this.description,derivedPrivateKey:this.key.toWif(),address:this.address,identityAttributes:this.getAttributes(),identityKey:this.identityKey,counter:this.counter}}getEncryptionKey(){return{privKey:this.key.deriveChild(this.key.toPublicKey(),Y),pubKey:this.key.deriveChild(this.key.toPublicKey(),Y).toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPrivateKeyWithSeed(j){let J=kj(Fj.sha256(j,"utf8")),$=`${p}-${P}-${J}`;return this.key.deriveChild(this.key.toPublicKey(),$)}getEncryptionKeyWithSeed(j){let J=this.getEncryptionPrivateKeyWithSeed(j);return{privKey:J,pubKey:J.toPublicKey()}}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z=q.toPublicKey(),Q=this.key.toPublicKey().constructor,W=$?Q.fromString($):z;return Mj(Oj(d(j),W,q))}decryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z;if($)z=Xj.fromString($);return Uj(Vj(d(j,"base64"),q,z))}exportForBackup(j){let J=this.export(),$=this.encrypt(JSON.stringify(J));return{wif:this.key.toWif(),id:$,...j&&{label:j},createdAt:new Date().toISOString()}}}var{toArray:L,toHex:_,toUTF8:y,toBase64:I}=_j,{electrumDecrypt:s,electrumEncrypt:g}=xj;class f extends B{#J;#j;#q;#Q=T;#W="";#$;#Z;#z;#w;idName;description;rootAddress;identityKey;identityAttributes;getApiData;constructor(j,J={},$=""){super();if(j instanceof Rj)if(this.#q=!1,$){let z=_(O.sha256($,"utf8")),Q=X.getSigningPathFromHex(z);this.#J=j.derive(Q)}else this.#J=j;else if(this.#q=!0,this.#j=j.rootPk,$){let z=_(O.sha256($,"utf8"));this.#j=this.#j.deriveChild(this.#j.toPublicKey(),z)}if(this.#w=$,this.idName="ID 1",this.description="",this.#$=`${M}/0/0/0`,this.#Z=`${M}/0/0/0`,this.#z=`${M}/0/0/1`,this.#q){if(!this.#j)throw new Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#$);this.rootAddress=z.toPublicKey().toAddress()}else{if(!this.#J)throw new Error("HD private key not initialized");let z=this.#J.derive(this.#$);this.rootAddress=z.privKey.toPublicKey().toAddress()}this.identityKey=this.deriveIdentityKey(this.rootAddress);let q={...J};this.identityAttributes=this.parseAttributes(q),this.getApiData=E(this.#Q,this.#W)}set BAP_SERVER(j){this.#Q=j}get BAP_SERVER(){return this.#Q}set BAP_TOKEN(j){this.#W=j}get BAP_TOKEN(){return this.#W}deriveIdentityKey(j){return H(j)}parseAttributes(j){if(typeof j==="string")return this.parseStringUrns(j);for(let J in j)if(!j[J].value||!j[J].nonce)throw new Error("Invalid identity attribute");return j||{}}parseStringUrns(j){let J={},$=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
5
+ `);for(let q of $){let Q=q.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");if(Q[0]==="urn"&&Q[1]==="bap"&&Q[2]==="id"&&Q[3]&&Q[4]&&Q[5])J[Q[3]]={value:Q[4],nonce:Q[5]}}return J}getIdentityKey(){return this.identityKey}set rootPath(j){if(this.#q){if(this.#$=j,!this.#j)throw new Error("Master private key not initialized");let J=this.#j.deriveChild(this.#j.toPublicKey(),j);this.rootAddress=J.toPublicKey().toAddress(),this.#Z=j,this.#z=j}else{let J=j;if(j.split("/").length<5)J=`${M}${j}`;if(!this.validatePath(J))throw new Error(`invalid signing path given ${J}`);if(this.#$=J,!this.#J)throw new Error("HD private key not initialized");let $=this.#J.derive(J);this.rootAddress=$.pubKey.toAddress(),this.#Z=J,this.#z=J}this.identityKey=this.deriveIdentityKey(this.rootAddress)}get rootPath(){return this.#$}getRootPath(){return this.#$}set currentPath(j){if(this.#q)this.#Z=this.#z,this.#z=j;else{let J=j;if(j.split("/").length<5)J=`${M}${j}`;if(!this.validatePath(J))throw new Error("invalid signing path given");this.#Z=this.#z,this.#z=J}}get currentPath(){return this.#z}get previousPath(){return this.#Z}get idSeed(){return this.#w}incrementPath(){this.currentPath=X.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=j.split("/");if(J.length===7&&Number(J[1].replace("'",""))<=F&&Number(J[2].replace("'",""))<=F&&Number(J[3].replace("'",""))<=F&&Number(J[4].replace("'",""))<=F&&Number(J[5].replace("'",""))<=F&&Number(J[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 J=[L(C),L("ID"),L(this.identityKey),L(this.getCurrentAddress())];return this.signOpReturnWithAIP(J,j||this.#Z)}getPathDerivedKey(j){if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");return this.#j.deriveChild(this.#j.toPublicKey(),j)}if(!this.#J)throw new Error("HD private key not initialized");return this.#J.derive(j).privKey}getIdentitySigningKeyForPath(j){let J=this.getPathDerivedKey(j);return J.deriveChild(J.toPublicKey(),k)}getMemberKey(){return this.getPathDerivedKey(this.#$).toPublicKey().toString()}getWalletRoot(j){return this.getPathDerivedKey(j||this.#z)}getWalletPubkey(j){return this.getWalletRoot(j).toPublicKey().toString()}getLegacyAddress(j){let J=j||this.#z;return this.getPathDerivedKey(J).toPublicKey().toAddress()}needsRotation(j){let J=j||this.rootAddress,$=this.getLegacyAddress(this.#$);return J===$}getLegacyRotationTransaction(){let j=this.getAddress(this.#$),J=[L(C),L("ID"),L(this.identityKey),L(j)],$=this.getAIPMessageBuffer(J),q=this.getPathDerivedKey(this.#$),{address:z,signature:Q}=this.signWithBSM($.flat(),q);return this.formatAIPOutput(J,z,Q)}getAddress(j){return this.getIdentitySigningKeyForPath(j).toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(this.#z)}getEncryptionKey(){if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),this.#$),q=$.deriveChild($.toPublicKey(),Y);return{privKey:q,pubKey:q.toPublicKey()}}if(!this.#J)throw new Error("HD private key not initialized");let J=this.#J.derive(this.#$).derive(Y).privKey;return{privKey:J,pubKey:J.toPublicKey()}}getEncryptionKeyType42(){if(this.#q)return this.getEncryptionKey();if(!this.#J)throw new Error("HD private key not initialized");let j=this.#J.derive(this.#$),J=j.privKey.deriveChild(j.toPublic().pubKey,Y);return{privKey:J,pubKey:J.toPublicKey()}}getEncryptionPublicKey(){let{pubKey:j}=this.getEncryptionKey();return j.toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encrypt(j,J){let{privKey:$,pubKey:q}=this.getEncryptionKey(),z=J?N.fromString(J):q;return I(g(L(j),z,$))}decrypt(j,J){let{privKey:$}=this.getEncryptionKey(),q;if(J)q=N.fromString(J);return y(s(L(j,"base64"),$,q))}encryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z=q.toPublicKey(),Q=$?N.fromString($):z;return I(g(L(j),Q,q))}decryptWithSeed(j,J,$){let q=this.getEncryptionPrivateKeyWithSeed(J),z;if($)z=N.fromString($);return y(s(L(j,"base64"),q,z))}getEncryptionPrivateKeyWithSeed(j){let J=_(O.sha256(j,"utf8"));if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");let z=this.#j.deriveChild(this.#j.toPublicKey(),this.#$);return z.deriveChild(z.toPublicKey(),J)}if(!this.#J)throw new Error("HD private key not initialized");let $=X.getSigningPathFromHex(J);return this.#J.derive(this.#$).derive($).privKey}getAttestation(j){let J=O.sha256(j,"utf8");return`bap:attest:${_(J)}:${this.getIdentityKey()}`}getAttestationHash(j){let J=this.getAttributeUrn(j);if(!J)return null;let $=this.getAttestation(J),q=O.sha256($,"utf8");return _(q)}signMessage(j,J){let $=J||this.#z,q=this.getIdentitySigningKeyForPath($);return this.signWithBSM(j,q)}signMessageWithSeed(j,J){let $=_(O.sha256(J,"utf8")),q;if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");let Q=this.#j.deriveChild(this.#j.toPublicKey(),this.#$);q=Q.deriveChild(Q.toPublicKey(),$)}else{if(!this.#J)throw new Error("HD private key not initialized");let Q=X.getSigningPathFromHex($);q=this.#J.derive(this.#$).derive(Q).privKey}let z=q.deriveChild(q.toPublicKey(),k);return this.signWithBSM(L(j,"utf8"),z)}signOpReturnWithAIP(j,J=""){let $=this.getAIPMessageBuffer(j),{address:q,signature:z}=this.signMessage($.flat(),J);return this.formatAIPOutput(j,q,z)}async getIdSigningKeys(){let j=await this.getApiData("/signing-keys",{idKey:this.identityKey});return console.log("getIdSigningKeys",j),j}async getAttributeAttestations(j){let J=this.getAttestationHash(j),$=await this.getApiData("/attestation/get",{hash:J});return console.log("getAttestations",j,J,$),$}import(j){this.idName=j.name,this.description=j.description||"",this.identityKey=j.identityKey,this.#$=j.rootPath,this.rootAddress=j.rootAddress,this.#Z=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.#Z,currentPath:this.#z,idSeed:this.#w,identityAttributes:this.getAttributes(),lastIdPath:""}}exportMemberBackup(){let j=this.getPathDerivedKey(this.#z),J=0,$=j.deriveChild(j.toPublicKey(),"bap:0"),q=$.deriveChild($.toPublicKey(),k);return{name:this.idName,description:this.description,derivedPrivateKey:j.toWif(),address:q.toPublicKey().toAddress(),identityAttributes:this.getAttributes(),identityKey:this.identityKey,counter:0}}newId(){this.incrementPath();let j=this.getPathDerivedKey(this.#z);return new V(j)}exportMember(){let j=this.exportMemberBackup(),J=this.getPathDerivedKey(this.#z),$=I(g(L(JSON.stringify(j)),J.toPublicKey()));return{wif:j.derivedPrivateKey,encryptedData:$}}}var{toArray:Z,toUTF8:x,toBase64:K,toHex:S}=Sj,{electrumEncrypt:i,electrumDecrypt:r}=Ej;class Dj{#J;#j;#q;#Q={};#W=T;#$="";#Z="";#z=0;getApiData;constructor(j,J="",$=""){if(!j)throw new Error("No key source given");if(typeof j==="string")this.#J=Tj.fromString(j),this.#q=!1;else this.#j=Nj.fromWif(j.rootPk),this.#q=!0;if(J)this.#$=J;if($)this.#W=$;this.getApiData=E(this.#W,this.#$)}get lastIdPath(){return this.#Z}getPublicKey(j=""){if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");if(j)return this.#j.deriveChild(this.#j.toPublicKey(),j).toPublicKey().toString();return this.#j.toPublicKey().toString()}if(!this.#J)throw new Error("HD private key not initialized");if(j)return this.#J.derive(j).pubKey.toString();return this.#J.pubKey.toString()}getHdPublicKey(j=""){if(this.#q)throw new Error("HD public keys are not available in Type 42 mode");if(!this.#J)throw new Error("HD private key not initialized");if(j)return this.#J.derive(j).toPublic().toString();return this.#J.toPublic().toString()}set BAP_SERVER(j){this.#W=j;for(let J in this.#Q)this.#Q[J].BAP_SERVER=j}get BAP_SERVER(){return this.#W}set BAP_TOKEN(j){this.#$=j;for(let J in this.#Q)this.#Q[J].BAP_TOKEN=j}get BAP_TOKEN(){return this.#$}checkIdBelongs(j){let J;if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");J=this.#j.deriveChild(this.#j.toPublicKey(),j.rootPath).toPublicKey().toAddress()}else{if(!this.#J)throw new Error("HD private key not initialized");J=this.#J.derive(j.rootPath).pubKey.toAddress()}if(J!==j.rootAddress)throw new Error("ID does not belong to this private key");return!0}listIds(){return Object.keys(this.#Q)}newId(j,J,$={},q=""){let z,Q,W;if(typeof j==="object"||j===void 0||typeof j==="string"&&j.startsWith("/"))Q=typeof j==="string"?j:void 0,W=typeof j==="object"?j:typeof J==="object"?J:{},z="Default Identity";else z=j,Q=typeof J==="string"?J:void 0,W=typeof J==="object"?J:$;let w;if(Q)w=Q;else if(this.#q)w=`bap:${this.#z}`,this.#z++;else w=this.getNextValidPath();let G;if(this.#q){if(!this.#j)throw new Error("Type 42 parameters not initialized");G=new f({rootPk:this.#j},W,q)}else{if(!this.#J)throw new Error("HD private key not initialized");G=new f(this.#J,W,q)}if(G.BAP_SERVER=this.#W,G.BAP_TOKEN=this.#$,G.idName=z,G.rootPath=w,this.#q)G.currentPath=w;else G.currentPath=X.getNextPath(w);let m=G.getIdentityKey();return this.#Q[m]=G,this.#Z=w,this.#Q[m]}removeId(j){delete this.#Q[j]}getNextValidPath(){if(this.#Z)return X.getNextIdentityPath(this.#Z);return`/0'/${Object.keys(this.#Q).length}'/0'`}newIdWithCounter(j,J=`Identity ${j}`){if(!this.#q)throw new Error("newIdWithCounter only works in Type 42 mode");let $=`bap:${j}`;return this.newId(J,$)}getId(j){return this.#Q[j]||null}setId(j){this.checkIdBelongs(j),this.#Q[j.getIdentityKey()]=j}importIds(j,J=!0){if(J&&typeof j==="string"){this.importEncryptedIds(j);return}let $=j;if(!$.lastIdPath)throw new Error("ID cannot be imported as it is not complete");if(!$.ids)throw new Error(`ID data is not in the correct format: ${j}`);let q=j.lastIdPath;for(let z of $.ids){if(!z.identityKey||!z.identityAttributes||!z.rootAddress)throw new Error("ID cannot be imported as it is not complete");let Q;if(this.#q){if(!this.#j)throw new Error("Type 42 parameters not initialized");Q=new f({rootPk:this.#j},{},z.idSeed)}else{if(!this.#J)throw new Error("HD private key not initialized");Q=new f(this.#J,{},z.idSeed)}if(Q.BAP_SERVER=this.#W,Q.BAP_TOKEN=this.#$,Q.import(z),q==="")q=Q.currentPath;if(this.checkIdBelongs(Q),this.#Q[Q.getIdentityKey()]=Q,this.#q&&Q.rootPath.startsWith("bap:")){let W=Q.rootPath.split(":");if(W.length>=2){let w=Number.parseInt(W[1],10);if(!Number.isNaN(w))this.#z=Math.max(this.#z,w+1)}}}this.#Z=q}importEncryptedIds(j){let J=this.decrypt(j),$=JSON.parse(J);if(Array.isArray($)){console.log(`Importing old format:
6
+ `,$),this.importOldIds($);return}if(typeof $!=="object")throw new Error("decrypted, but found unrecognized identities format");this.importIds($,!1)}importOldIds(j){for(let J of j){let $;if(this.#q){if(!this.#j)throw new Error("Type 42 parameters not initialized");$=new f({rootPk:this.#j},{},J.idSeed??"")}else{if(!this.#J)throw new Error("HD private key not initialized");$=new f(this.#J,{},J.idSeed??"")}$.BAP_SERVER=this.#W,$.BAP_TOKEN=this.#$,$.import(J),this.checkIdBelongs($),this.#Q[$.getIdentityKey()]=$,this.#Z=$.currentPath}}exportIds(j,J=!0){let $={lastIdPath:this.#Z,ids:[]},q=j||Object.keys(this.#Q);for(let z of q){if(!this.#Q[z])throw new Error(`Identity ${z} not found`);$.ids.push(this.#Q[z].export())}if(J)return this.encrypt(JSON.stringify($));return $}exportId(j,J=!0){let $={lastIdPath:this.#Z,ids:[]};if($.ids.push(this.#Q[j].export()),J)return this.encrypt(JSON.stringify($));return $}encrypt(j){if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),Y);return K(i(Z(j),$.toPublicKey(),null))}if(!this.#J)throw new Error("HD private key not initialized");let J=this.#J.derive(Y);return K(i(Z(j),J.pubKey,null))}decrypt(j){if(this.#q){if(!this.#j)throw new Error("Master private key not initialized");let $=this.#j.deriveChild(this.#j.toPublicKey(),Y);return x(r(Z(j,"base64"),$))}if(!this.#J)throw new Error("HD private key not initialized");let J=this.#J.derive(Y);return x(r(Z(j,"base64"),J.privKey))}signAttestationWithAIP(j,J,$=0,q=""){let z=this.getId(J);if(!z)throw new Error("Could not find identity to attest with");let Q=this.getAttestationBuffer(j,$,q),{address:W,signature:w}=z.signMessage(Q);return this.createAttestationTransaction(j,$,W,w,q)}verifyAttestationWithAIP(j){if(!j.every((q)=>Array.isArray(q))||j[0][0]!==l.OP_RETURN||S(j[1])!==h)throw new Error("Not a valid BAP transaction");let J=S(j[7])==="44415441"?5:0,$={type:x(j[2]),hash:S(j[3]),sequence:x(j[4]),signingProtocol:x(j[7+J]),signingAddress:x(j[8+J]),signature:K(j[9+J])};if(J&&j[3]===j[8])$.data=S(j[9]);console.log({attestation:$});try{let q=[];for(let z=0;z<6+J;z++)q.push(j[z]);$.verified=this.verifySignature(q.flat(),$.signingAddress,$.signature)}catch{$.verified=!1}return $}createAttestationTransaction(j,J,$,q,z=""){let Q=[[l.OP_RETURN],Z(C),Z("ATTEST"),Z(j),Z(`${J}`),Z("|")];if(z)Q.push(Z(C),Z("DATA"),Z(j),Z(z),Z("|"));return Q.push(Z(R),Z("BITCOIN_ECDSA"),Z($),Z(q,"base64")),console.log({elements:Q}),Q}getAttestationBuffer(j,J=0,$=""){let q=[[l.OP_RETURN],Z(C),Z("ATTEST"),Z(j),Z(`${J}`),Z("|")];if($)q.push(Z(C),Z("DATA"),Z(j),Z($),Z("|"));return q.flat()}verifySignature(j,J,$){let q;if(Array.isArray(j))q=j;else if(Buffer.isBuffer(j))q=[...j];else q=Z(j,"utf8");let z=Hj.fromCompact($,"base64"),Q;for(let W=0;W<4;W++)try{if(Q=z.RecoverPublicKey(W,new Bj(A.magicHash(q))),A.verify(q,z,Q)&&Q.toAddress()===J)return!0}catch{}return!1}async verifyChallengeSignature(j,J,$,q){if(!this.verifySignature($,J,q))return!1;try{let Q=await this.getApiData("/attestation/valid",{idKey:j,address:J,challenge:$,signature:q});if(Q?.status==="success"&&Q?.result?.valid===!0)return!0;return!1}catch(Q){return console.error("API call failed:",Q),!1}}async isValidAttestationTransaction(j){if(this.verifyAttestationWithAIP(j))return this.getApiData("/attestation/valid",{tx:j});return!1}async getIdentityFromAddress(j){return this.getApiData("/identity/validByAddress",{address:j})}async getIdentity(j){return this.getApiData("/identity/get",{idKey:j})}async getAttestationsForHash(j){return this.getApiData("/attestations",{hash:j})}exportForBackup(j,J,$){let z={ids:this.exportIds(),...j&&{label:j},createdAt:new Date().toISOString()};if(this.#q){if(!this.#j)throw new Error("Type 42 parameters not initialized");return{...z,rootPk:this.#j.toWif()}}if(!this.#J)throw new Error("HD private key not initialized");return{...z,xprv:J||this.#J.toString(),mnemonic:$||""}}exportMemberForBackup(j,J){let $=this.#Q[j];if(!$)throw new Error(`Identity ${j} not found`);let q=$.exportMember();return{wif:q.wif,id:q.encryptedData,...J&&{label:J},createdAt:new Date().toISOString()}}}export{qj as bapIdFromPubkey,H as bapIdFromAddress,V as MemberID,f as MasterID,Dj as BAP};
7
7
 
8
- //# debugId=29AD2D5A28DD750864756E2164756E21
8
+ //# debugId=63B1716DC5B0062564756E2164756E21