bsv-bap 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,36 +1,63 @@
1
- import type { Attestation, Identity } from "./interface";
2
- export interface APIResponse<T = Attestation | Identity> {
3
- status: string;
1
+ import type { Organization, Person, WithContext } from 'schema-dts';
2
+ export interface APIResponse<T> {
3
+ status: 'success' | 'error';
4
4
  result?: T;
5
5
  message?: string;
6
6
  }
7
- export type GetAttestationResponse = APIResponse<Attestation>;
8
- export type GetIdentityResponse = APIResponse<Identity>;
9
- export type GetIdentityByAddressResponse = APIResponse<Identity>;
10
- export type GetIdentityDIDResponse = string;
11
- export type GetIdentityDIDByAddressResponse = string;
12
- export interface AttestationValidParams {
13
- address: string;
7
+ export interface Signer {
14
8
  idKey: string;
15
- attribute: string;
16
- value: string;
17
- nonce: string;
18
- urn: string;
9
+ signingAddress: string;
10
+ sequence: number;
11
+ block: number;
12
+ txId: string;
13
+ timestamp: number;
14
+ revoked: boolean;
15
+ }
16
+ export interface Attestation {
19
17
  hash: string;
18
+ attribute?: string;
19
+ value?: string;
20
+ nonce?: string;
21
+ urn?: string;
22
+ signers: Signer[];
23
+ }
24
+ export interface SigningKey {
25
+ idKey: string;
26
+ signingAddress: string;
27
+ sequence: number;
20
28
  block: number;
29
+ txId: string;
21
30
  timestamp: number;
31
+ revoked: boolean;
22
32
  }
23
- export interface IdentityValidByAddressParams {
33
+ export type GetSigningKeysResponse = APIResponse<Signer[]>;
34
+ export interface APIIdentityAddress {
24
35
  address: string;
36
+ txId: string;
25
37
  block: number;
26
- timestamp: number;
38
+ }
39
+ export type APISchemaIdentity = WithContext<Person | Organization>;
40
+ export interface APIIdentity {
41
+ idKey: string;
42
+ firstSeen: number;
43
+ rootAddress: string;
44
+ currentAddress: string;
45
+ addresses: APIIdentityAddress[];
46
+ identity?: APISchemaIdentity;
27
47
  }
28
48
  export interface ValidityRecord {
29
49
  valid: boolean;
30
50
  block: number;
31
51
  timestamp: number;
32
52
  }
33
- export interface AttestationValidResponse extends ValidityRecord {
53
+ export interface Profile {
54
+ _id: string;
55
+ data: WithContext<Person | Organization>;
34
56
  }
35
- export interface IdentityValidResponse extends Identity, ValidityRecord {
57
+ export interface IdentityValidResponse extends APIIdentity, ValidityRecord {
58
+ profile?: Profile;
36
59
  }
60
+ export type GetAttestationResponse = APIResponse<Attestation>;
61
+ export type GetIdentityResponse = APIResponse<APIIdentity>;
62
+ export type GetIdentityByAddressResponse = APIResponse<APIIdentity>;
63
+ export type AttestationValidResponse = APIResponse<ValidityRecord>;
package/dist/id.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { type HD } from "@bsv/sdk";
1
+ import { HD, type PrivateKey } from "@bsv/sdk";
2
2
  import { type APIFetcher } from "./api";
3
- import type { Identity, IdentityAttribute, IdentityAttributes } from "./interface";
4
- import type { GetAttestationResponse } from "./apiTypes";
3
+ import type { GetAttestationResponse, GetSigningKeysResponse } from "./apiTypes";
4
+ import type { Identity, IdentityAttribute, IdentityAttributes, OldIdentity } from "./interface";
5
5
  /**
6
6
  * BAP_ID class
7
7
  *
@@ -9,19 +9,22 @@ import type { GetAttestationResponse } from "./apiTypes";
9
9
  *
10
10
  * @type {BAP_ID}
11
11
  */
12
- declare class BAP_ID {
12
+ export declare class BAP_ID {
13
13
  #private;
14
- idName: string;
14
+ lastIdPath: string;
15
+ name: string;
15
16
  description: string;
16
- rootAddress: string;
17
17
  identityKey: string;
18
+ rootAddress: string;
18
19
  identityAttributes: IdentityAttributes;
20
+ private BAP_SERVER_;
21
+ private BAP_TOKEN_;
19
22
  getApiData: APIFetcher;
20
- constructor(HDPrivateKey: HD, identityAttributes?: IdentityAttributes, idSeed?: string);
21
- set BAP_SERVER(bapServer: string);
23
+ constructor(key: HD | PrivateKey, identityAttributes?: IdentityAttributes, idSeed?: string);
22
24
  get BAP_SERVER(): string;
23
- set BAP_TOKEN(token: string);
25
+ set BAP_SERVER(value: string);
24
26
  get BAP_TOKEN(): string;
27
+ set BAP_TOKEN(value: string);
25
28
  deriveIdentityKey(address: string): string;
26
29
  /**
27
30
  * Helper function to parse identity attributes
@@ -69,6 +72,8 @@ declare class BAP_ID {
69
72
  * @returns {{}|null}
70
73
  */
71
74
  setAttribute(attributeName: string, attributeValue: string | Record<string, string>): void;
75
+ private updateExistingAttribute;
76
+ private createNewAttribute;
72
77
  /**
73
78
  * Unset the given attribute from the ID
74
79
  *
@@ -96,7 +101,7 @@ declare class BAP_ID {
96
101
  * @param value
97
102
  * @param nonce
98
103
  */
99
- addAttribute(attributeName: string, value: any, nonce?: string): void;
104
+ addAttribute(attributeName: string, value: string, nonce?: string): void;
100
105
  /**
101
106
  * This should be called with the last part of the signing path (/.../.../...)
102
107
  * This library assumes the first part is m/424150'/0'/0' as defined at the top of this file
@@ -148,7 +153,7 @@ declare class BAP_ID {
148
153
  */
149
154
  getIdTransaction(previousPath?: string): string[];
150
155
  /**
151
- * Get address for given path
156
+ * Get address for given path. Only works if HDPrivateKey is set
152
157
  *
153
158
  * @param path
154
159
  * @returns {*}
@@ -161,38 +166,29 @@ declare class BAP_ID {
161
166
  */
162
167
  getCurrentAddress(): string;
163
168
  /**
164
- * Get the public key for encrypting data for this identity
169
+ * Get the encryption public key for this identity
170
+ * This key is derived from the identity's root path + ENCRYPTION_PATH
165
171
  */
166
172
  getEncryptionPublicKey(): string;
167
173
  /**
168
- * Get the public key for encrypting data for this identity, using a seed for the encryption
174
+ * Get the encryption public key for this identity with a seed
175
+ * This key is derived from the identity's root path + ENCRYPTION_PATH + seed path
169
176
  */
170
177
  getEncryptionPublicKeyWithSeed(seed: string): string;
171
178
  /**
172
- * Encrypt the given string data with the identity encryption key
173
- * @param stringData
174
- * @param counterPartyPublicKey Optional public key of the counterparty
175
- * @return string Base64
179
+ * Encrypt data using this identity's encryption key
176
180
  */
177
181
  encrypt(stringData: string, counterPartyPublicKey?: string): string;
178
182
  /**
179
- * Decrypt the given ciphertext with the identity encryption key
180
- * @param ciphertext
183
+ * Decrypt data using this identity's encryption key
181
184
  */
182
185
  decrypt(ciphertext: string, counterPartyPublicKey?: string): string;
183
186
  /**
184
- * Encrypt the given string data with the identity encryption key
185
- * @param stringData
186
- * @param seed String seed
187
- * @param counterPartyPublicKey Optional public key of the counterparty
188
- * @return string Base64
187
+ * Encrypt data using this identity's encryption key with a seed
189
188
  */
190
189
  encryptWithSeed(stringData: string, seed: string, counterPartyPublicKey?: string): string;
191
190
  /**
192
- * Decrypt the given ciphertext with the identity encryption key
193
- * @param ciphertext
194
- * @param seed String seed
195
- // * @param counterPartyPublicKey Public key of the counterparty
191
+ * Decrypt data using this identity's encryption key with a seed
196
192
  */
197
193
  decryptWithSeed(ciphertext: string, seed: string, counterPartyPublicKey?: string): string;
198
194
  private getEncryptionPrivateKeyWithSeed;
@@ -217,7 +213,7 @@ declare class BAP_ID {
217
213
  * @param signingPath
218
214
  * @returns {{address: string, signature: string}}
219
215
  */
220
- signMessage(message: string | Buffer, signingPath?: string): {
216
+ signMessage(msg: string | Buffer, signingPath?: string): {
221
217
  address: string;
222
218
  signature: string;
223
219
  };
@@ -254,7 +250,7 @@ declare class BAP_ID {
254
250
  /**
255
251
  * Get all signing keys for this identity
256
252
  */
257
- getIdSigningKeys(): Promise<any>;
253
+ getIdSigningKeys(): Promise<GetSigningKeysResponse>;
258
254
  /**
259
255
  * Get all attestations for the given attribute
260
256
  *
@@ -266,11 +262,10 @@ declare class BAP_ID {
266
262
  *
267
263
  * @param identity{{}}
268
264
  */
269
- import(identity: Identity): void;
265
+ import(id: Identity | OldIdentity): void;
270
266
  /**
271
267
  * Export this identity to a JSON object
272
268
  * @returns {{}}
273
269
  */
274
270
  export(): Identity;
275
271
  }
276
- export { BAP_ID };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,14 @@
1
+ import { HD, PrivateKey } from "@bsv/sdk";
1
2
  import { type APIFetcher } from "./api";
2
- import type { GetAttestationResponse, GetIdentityByAddressResponse } from "./apiTypes";
3
+ import type { AttestationValidResponse, GetAttestationResponse, GetIdentityByAddressResponse, GetIdentityResponse } from "./apiTypes";
3
4
  import { BAP_ID } from "./id";
4
- import type { Attestation, Identity, IdentityAttributes, PathPrefix } from "./interface";
5
+ import type { Attestation, HDIdentity, Identity, IdentityAttributes, OldIdentity, PathPrefix, SingleKeyIdentity } from "./interface";
5
6
  type Identities = {
6
7
  lastIdPath: string;
7
8
  ids: Identity[];
8
9
  };
10
+ export type { HDIdentity, SingleKeyIdentity, Attestation, Identity, IdentityAttributes, PathPrefix };
11
+ export { BAP_ID };
9
12
  /**
10
13
  * BAP class
11
14
  *
@@ -15,21 +18,22 @@ type Identities = {
15
18
  */
16
19
  export declare class BAP {
17
20
  #private;
18
- getApiData: APIFetcher;
19
- constructor(HDPrivateKey: string, token?: string, server?: string);
20
21
  get lastIdPath(): string;
22
+ getApiData: APIFetcher;
23
+ constructor(key: string | HD | PrivateKey, token?: string);
24
+ private isHD;
21
25
  /**
22
- * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty
26
+ * Get the public key of the given childPath, or of the current HDPrivateKey if childPath is empty
23
27
  *
24
28
  * @param childPath Full derivation path for this child
25
- * @returns {*}
29
+ * @returns {string}
26
30
  */
27
31
  getPublicKey(childPath?: string): string;
28
32
  /**
29
- * Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty
33
+ * Get the HD public key (xpub) of the given childPath, or of the current HDPrivateKey if childPath is empty
30
34
  *
31
35
  * @param childPath Full derivation path for this child
32
- * @returns {*}
36
+ * @returns {string}
33
37
  */
34
38
  getHdPublicKey(childPath?: string): string;
35
39
  set BAP_SERVER(bapServer: string);
@@ -104,28 +108,15 @@ export declare class BAP {
104
108
  */
105
109
  importIds(idData: Identities | string, encrypted?: boolean): void;
106
110
  importEncryptedIds(idData: string): void;
107
- importOldIds(idData: Identity[]): void;
111
+ importOldIds(idData: OldIdentity[]): void;
108
112
  /**
109
- * Export all the IDs of this instance for external storage
110
- *
111
- * By default this function will encrypt the data, using a derivative child of the main HD key
112
- *
113
- * @param encrypted Whether the data should be encrypted (default true)
114
- * @returns {[]|*}
113
+ * Export identities. If no idKeys are provided, exports all identities.
114
+ * @param encrypted Whether to encrypt the export. Defaults to true
115
+ * @param idKeys Optional array of identity keys to export
116
+ * @returns A string if encrypted is true, otherwise an Identities object
115
117
  */
116
- exportIds(encrypted?: true): string;
117
- exportIds(encrypted: false): Identities;
118
- /**
119
- * Export a given ID from this instance for external storage
120
- *
121
- * By default this function will encrypt the data, using a derivative child of the main HD key
122
- *
123
- * @param idKey The key of the identity to export
124
- * @param encrypted Whether the data should be encrypted (default true)
125
- * @returns {[]|*}
126
- */
127
- exportId(idKey: string, encrypted?: true): string;
128
- exportId(idKey: string, encrypted: false): Identities;
118
+ exportIds(encrypted?: true, idKeys?: string[]): string;
119
+ exportIds(encrypted: false, idKeys?: string[]): Identities;
129
120
  /**
130
121
  * Encrypt a string of data
131
122
  *
@@ -219,7 +210,7 @@ export declare class BAP {
219
210
  * @param tx
220
211
  * @returns {Promise<boolean|*>}
221
212
  */
222
- isValidAttestationTransaction(tx: string[]): Promise<any>;
213
+ isValidAttestationTransaction(tx: string[]): Promise<AttestationValidResponse | false>;
223
214
  /**
224
215
  * Get all signing keys for the given idKey
225
216
  *
@@ -233,7 +224,7 @@ export declare class BAP {
233
224
  * @param idKey
234
225
  * @returns {Promise<*>}
235
226
  */
236
- getIdentity(idKey: string): Promise<any>;
227
+ getIdentity(idKey: string): Promise<GetIdentityResponse>;
237
228
  /**
238
229
  * Get all attestations for the given attestation hash
239
230
  *
@@ -241,4 +232,5 @@ export declare class BAP {
241
232
  */
242
233
  getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse>;
243
234
  }
244
- export { BAP_ID };
235
+ export declare function isSingleKeyIdentity(id: Identity): id is SingleKeyIdentity;
236
+ export declare function isHDIdentity(id: Identity): id is HDIdentity;
@@ -1,2 +1,7 @@
1
- import{Hash as t,PublicKey as e,BSM as i,BigNumber as r,Utils as s,ECIES as n,HD as o,Signature as h}from"@bsv/sdk";import a from"randombytes";function d(t,e){if(!{}.hasOwnProperty.call(t,e))throw new TypeError("attempted to use private field on non-instance");return t}var u=0;function c(t){return"__private_"+u+++"_"+t}function f(){return f=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var r in i)({}).hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t},f.apply(null,arguments)}const g=(t,e)=>async(i,r)=>(async(t,e,i,r)=>{const s=`${i}${t}`;return(await fetch(s,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:r,format:"json"},body:JSON.stringify(e)})).json()})(i,r,t,e),y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",l=`0x${Buffer.from(y).toString("hex")}`,p="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva";Buffer.from(p).toString("hex");const A="https://api.sigmaidentity.com/v1",v=2147483647,P="m/424150'/0'/0'",b="m/424150'/2147483647'/2147483647'",m={hexEncode:t=>`0x${Buffer.from(t).toString("hex")}`,hexDecode:(t,e="utf8")=>Buffer.from(t.replace("0x",""),"hex").toString(e),getRandomString:(t=32)=>a(t).toString("hex"),isHex:t=>"string"==typeof t&&/^[0-9a-fA-F]+$/.test(t),getSigningPathFromHex(t,e=!0){let i="m";const r=t.match(/.{1,8}/g);if(!r)throw new Error("Invalid hex string");const s=2147483647;for(const t of r){let r=Number(`0x${t}`);r>s&&(r-=s),i+=`/${r}${e?"'":""}`}return i},getNextIdentityPath(t){const e=t.split("/"),i=e[e.length-2];let r=!1;i.match("'")&&(r=!0);const s=(Number(i.replace(/[^0-9]/g,""))+1).toString();return e[e.length-2]=s+(r?"'":""),e[e.length-1]="0"+(r?"'":""),e.join("/")},getNextPath(t){const e=t.split("/"),i=e[e.length-1];let r=!1;i.match("'")&&(r=!0);const s=(Number(i.replace(/[^0-9]/g,""))+1).toString();return e[e.length-1]=s+(r?"'":""),e.join("/")}},{toArray:S,toHex:x,toBase58:B,toUTF8:K,toBase64:E}=s,{electrumDecrypt:I,electrumEncrypt:w}=n,{magicHash:N}=i;var O=/*#__PURE__*/c("HDPrivateKey"),D=/*#__PURE__*/c("BAP_SERVER"),T=/*#__PURE__*/c("BAP_TOKEN"),R=/*#__PURE__*/c("rootPath"),$=/*#__PURE__*/c("previousPath"),_=/*#__PURE__*/c("currentPath"),j=/*#__PURE__*/c("idSeed");class C{constructor(e,i={},r=""){if(Object.defineProperty(this,O,{writable:!0,value:void 0}),Object.defineProperty(this,D,{writable:!0,value:A}),Object.defineProperty(this,T,{writable:!0,value:""}),Object.defineProperty(this,R,{writable:!0,value:void 0}),Object.defineProperty(this,$,{writable:!0,value:void 0}),Object.defineProperty(this,_,{writable:!0,value:void 0}),Object.defineProperty(this,j,{writable:!0,value:void 0}),this.idName=void 0,this.description=void 0,this.rootAddress=void 0,this.identityKey=void 0,this.identityAttributes=void 0,this.getApiData=void 0,d(this,j)[j]=r,r){const i=x(t.sha256(r,"utf8")),s=m.getSigningPathFromHex(i);d(this,O)[O]=e.derive(s)}else d(this,O)[O]=e;this.idName="ID 1",this.description="",d(this,R)[R]=`${P}/0/0/0`,d(this,$)[$]=`${P}/0/0/0`,d(this,_)[_]=`${P}/0/0/1`;const s=d(this,O)[O].derive(d(this,R)[R]);this.rootAddress=s.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);const n=f({},i);this.identityAttributes=this.parseAttributes(n),this.getApiData=g(d(this,D)[D],d(this,T)[T])}set BAP_SERVER(t){d(this,D)[D]=t}get BAP_SERVER(){return d(this,D)[D]}set BAP_TOKEN(t){d(this,T)[T]=t}get BAP_TOKEN(){return d(this,T)[T]}deriveIdentityKey(e){const i=x(t.sha256(e,"utf8"));return B(t.ripemd160(i,"hex"))}parseAttributes(t){if("string"==typeof t)return this.parseStringUrns(t);for(const e in t)if(!t[e].value||!t[e].nonce)throw new Error("Invalid identity attribute");return t||{}}parseStringUrns(t){const e={},i=t.replace(/^\s+/g,"").replace(/\r/gm,"").split("\n");for(const t of i){const i=t.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");"urn"===i[0]&&"bap"===i[1]&&"id"===i[2]&&i[3]&&i[4]&&i[5]&&(e[i[3]]={value:i[4],nonce:i[5]})}return e}getIdentityKey(){return this.identityKey}getAttributes(){return this.identityAttributes}getAttribute(t){return this.identityAttributes[t]?this.identityAttributes[t]:null}setAttribute(t,e){e&&(this.identityAttributes[t]?this.identityAttributes[t].value=e:this.addAttribute(t,e))}unsetAttribute(t){delete this.identityAttributes[t]}getAttributeUrns(){let t="";for(const e in this.identityAttributes){const i=this.getAttributeUrn(e);i&&(t+=`${i}\n`)}return t}getAttributeUrn(t){const e=this.identityAttributes[t];return e?`urn:bap:id:${t}:${e.value}:${e.nonce}`:null}addAttribute(t,e,i=""){let r=i;i||(r=m.getRandomString()),this.identityAttributes[t]={value:e,nonce:r}}set rootPath(t){if(d(this,O)[O]){let e=t;if(t.split("/").length<5&&(e=`${P}${t}`),!this.validatePath(e))throw new Error(`invalid signing path given ${e}`);d(this,R)[R]=e;const i=d(this,O)[O].derive(e);this.rootAddress=i.pubKey.toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress),d(this,$)[$]=e,d(this,_)[_]=e}}get rootPath(){return d(this,R)[R]}getRootPath(){return d(this,R)[R]}set currentPath(t){let e=t;if(t.split("/").length<5&&(e=`${P}${t}`),!this.validatePath(e))throw new Error("invalid signing path given");d(this,$)[$]=d(this,_)[_],d(this,_)[_]=e}get currentPath(){return d(this,_)[_]}get previousPath(){return d(this,$)[$]}get idSeed(){return d(this,j)[j]}incrementPath(){this.currentPath=m.getNextPath(this.currentPath)}validatePath(t){if(t.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}'?/)){const e=t.split("/");if(7===e.length&&Number(e[1].replace("'",""))<=v&&Number(e[2].replace("'",""))<=v&&Number(e[3].replace("'",""))<=v&&Number(e[4].replace("'",""))<=v&&Number(e[5].replace("'",""))<=v&&Number(e[6].replace("'",""))<=v)return!0}return!1}getInitialIdTransaction(){return this.getIdTransaction(d(this,R)[R])}getIdTransaction(t=""){if(d(this,_)[_]===d(this,R)[R])throw new Error("Current path equals rootPath. ID was probably not initialized properly");const e=[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(e,t||d(this,$)[$])}getAddress(t){return d(this,O)[O].derive(t).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(d(this,_)[_])}getEncryptionPublicKey(){return d(this,O)[O].derive(d(this,R)[R]).derive(b).privKey.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(t){return this.getEncryptionPrivateKeyWithSeed(t).toPublicKey().toString("hex")}encrypt(t,i){const r=d(this,O)[O].derive(d(this,R)[R]).derive(b).privKey.toPublicKey(),s=i?e.fromString(i):r;return E(w(S(t),s,null))}decrypt(t,i){const r=d(this,O)[O].derive(d(this,R)[R]).derive(b).privKey;let s;return i&&(s=e.fromString(i)),K(I(S(t,"base64"),r,s))}encryptWithSeed(t,i,r){const s=this.getEncryptionPrivateKeyWithSeed(i),n=s.toPublicKey(),o=r?e.fromString(r):n;return E(w(S(t),o,s))}decryptWithSeed(t,i,r){const s=this.getEncryptionPrivateKeyWithSeed(i);let n;return r&&(n=e.fromString(r)),K(I(S(t,"base64"),s,n))}getEncryptionPrivateKeyWithSeed(e){const i=x(t.sha256(e,"utf8")),r=m.getSigningPathFromHex(i);return d(this,O)[O].derive(d(this,R)[R]).derive(r).privKey}getAttestation(e){const i=t.sha256(e,"utf8");return`bap:attest:${x(i)}:${this.getIdentityKey()}`}getAttestationHash(e){const i=this.getAttributeUrn(e);if(!i)return null;const r=this.getAttestation(i),s=t.sha256(r,"utf8");return x(s)}signMessage(t,e=""){let s;s=t instanceof Buffer?t:Buffer.from(t);const n=e||d(this,_)[_],o=d(this,O)[O].derive(n).privKey,h=o.toAddress(),a=i.sign(S(t),o,"raw"),u=new r(N(S(t,"utf8"))),c=a.CalculateRecoveryFactor(o.toPublicKey(),u);return{address:h,signature:i.sign(S(s),o,"raw").toCompact(c,!0,"base64")}}signMessageWithSeed(e,s){const n=x(t.sha256(s,"utf8")),o=m.getSigningPathFromHex(n),h=d(this,O)[O].derive(d(this,R)[R]).derive(o),a=h.privKey.toPublicKey().toAddress(),u=i.sign(S(e),h.privKey,"raw"),c=new r(N(S(e,"utf8"))),f=u.CalculateRecoveryFactor(h.privKey.toPublicKey(),c);return{address:a,signature:i.sign(S(Buffer.from(e)),h.privKey,"raw").toCompact(f,!0,"base64")}}signOpReturnWithAIP(t,e="",i="hex"){const r=this.getAIPMessageBuffer(t),{address:s,signature:n}=this.signMessage(r,e);return t.concat([Buffer.from("|").toString(i),Buffer.from(p).toString(i),Buffer.from("BITCOIN_ECDSA").toString(i),Buffer.from(s).toString(i),Buffer.from(n,"base64").toString(i)])}getAIPMessageBuffer(t){const e=[];"6a"!==t[0].replace("0x","")&&e.push(Buffer.from("6a","hex"));for(const i of t)e.push(Buffer.from(i.replace("0x",""),"hex"));return e.push(Buffer.from("|")),Buffer.concat([...e])}async getIdSigningKeys(){const t=await this.getApiData("/signing-keys",{idKey:this.identityKey});return console.log("getIdSigningKeys",t),t}async getAttributeAttestations(t){const e=this.getAttestationHash(t),i=await this.getApiData("/attestation/get",{hash:e});return console.log("getAttestations",t,e,i),i}import(t){this.idName=t.name,this.description=t.description||"",this.identityKey=t.identityKey,d(this,R)[R]=t.rootPath,this.rootAddress=t.rootAddress,d(this,$)[$]=t.previousPath,d(this,_)[_]=t.currentPath,d(this,j)[j]=t.idSeed||"",this.identityAttributes=this.parseAttributes(t.identityAttributes)}export(){return{name:this.idName,description:this.description,identityKey:this.identityKey,rootPath:d(this,R)[R],rootAddress:this.rootAddress,previousPath:d(this,$)[$],currentPath:d(this,_)[_],idSeed:d(this,j)[j],identityAttributes:this.getAttributes(),lastIdPath:""}}}const{toArray:H,toUTF8:V,toBase64:W}=s,{electrumEncrypt:F,electrumDecrypt:U}=n;var k=/*#__PURE__*/c("HDPrivateKey"),M=/*#__PURE__*/c("ids"),J=/*#__PURE__*/c("BAP_SERVER"),G=/*#__PURE__*/c("BAP_TOKEN"),q=/*#__PURE__*/c("lastIdPath");class z{constructor(t,e="",i=""){if(Object.defineProperty(this,k,{writable:!0,value:void 0}),Object.defineProperty(this,M,{writable:!0,value:{}}),Object.defineProperty(this,J,{writable:!0,value:A}),Object.defineProperty(this,G,{writable:!0,value:""}),Object.defineProperty(this,q,{writable:!0,value:""}),this.getApiData=void 0,!t)throw new Error("No HDPrivateKey given");d(this,k)[k]=o.fromString(t),e&&(d(this,G)[G]=e),i&&(d(this,J)[J]=i),this.getApiData=g(d(this,J)[J],d(this,G)[G])}get lastIdPath(){return d(this,q)[q]}getPublicKey(t=""){return t?d(this,k)[k].derive(t).pubKey.toString():d(this,k)[k].pubKey.toString()}getHdPublicKey(t=""){return t?d(this,k)[k].derive(t).toPublic().toString():d(this,k)[k].toPublic().toString()}set BAP_SERVER(t){d(this,J)[J]=t;for(const e in d(this,M)[M])d(this,M)[M][e].BAP_SERVER=t}get BAP_SERVER(){return d(this,J)[J]}set BAP_TOKEN(t){d(this,G)[G]=t;for(const e in d(this,M)[M])d(this,M)[M][e].BAP_TOKEN=t}get BAP_TOKEN(){return d(this,G)[G]}checkIdBelongs(t){if(d(this,k)[k].derive(t.rootPath).pubKey.toAddress()!==t.rootAddress)throw new Error("ID does not belong to this private key");return!0}listIds(){return Object.keys(d(this,M)[M])}newId(t,e={},i=""){let r;r=t||this.getNextValidPath();const s=new C(d(this,k)[k],e,i);s.BAP_SERVER=d(this,J)[J],s.BAP_TOKEN=d(this,G)[G],s.rootPath=r,s.currentPath=m.getNextPath(r);const n=s.getIdentityKey();return d(this,M)[M][n]=s,d(this,q)[q]=r,d(this,M)[M][n]}removeId(t){delete d(this,M)[M][t]}getNextValidPath(){return d(this,q)[q]?m.getNextIdentityPath(d(this,q)[q]):`/0'/${Object.keys(d(this,M)[M]).length}'/0'`}getId(t){return d(this,M)[M][t]||null}setId(t){this.checkIdBelongs(t),d(this,M)[M][t.getIdentityKey()]=t}importIds(t,e=!0){if(e&&"string"==typeof t)return void this.importEncryptedIds(t);const i=t;if(!i.lastIdPath)throw new Error("ID cannot be imported as it is not complete");if(!i.ids)throw new Error(`ID data is not in the correct format: ${t}`);let r=t.lastIdPath;for(const t of i.ids){if(!t.identityKey||!t.identityAttributes||!t.rootAddress)throw new Error("ID cannot be imported as it is not complete");const e=new C(d(this,k)[k],{},t.idSeed);e.BAP_SERVER=d(this,J)[J],e.BAP_TOKEN=d(this,G)[G],e.import(t),""===r&&(r=e.currentPath),this.checkIdBelongs(e),d(this,M)[M][e.getIdentityKey()]=e}d(this,q)[q]=r}importEncryptedIds(t){const e=this.decrypt(t),i=JSON.parse(e);if(Array.isArray(i))return console.log("Importing old format:\n",i),void this.importOldIds(i);if("object"!=typeof i)throw new Error("decrypted, but found unrecognized identities format");this.importIds(i,!1)}importOldIds(t){for(const e of t){const t=new C(d(this,k)[k],{},e.idSeed);t.BAP_SERVER=d(this,J)[J],t.BAP_TOKEN=d(this,G)[G],t.import(e),this.checkIdBelongs(t),d(this,M)[M][t.getIdentityKey()]=t,d(this,q)[q]=t.currentPath}}exportIds(t=!0){const e={lastIdPath:d(this,q)[q],ids:[]};for(const t in d(this,M)[M])e.ids.push(d(this,M)[M][t].export());return t?this.encrypt(JSON.stringify(e)):e}exportId(t,e=!0){const i={lastIdPath:d(this,q)[q],ids:[]};return i.ids.push(d(this,M)[M][t].export()),e?this.encrypt(JSON.stringify(i)):i}encrypt(t){const e=d(this,k)[k].derive(b);return W(F(H(t),e.pubKey,null))}decrypt(t){const e=d(this,k)[k].derive(b);return V(U(H(t,"base64"),e.privKey))}signAttestationWithAIP(t,e,i=0,r=""){const s=this.getId(e);if(!s)throw new Error("Could not find identity to attest with");const n=this.getAttestationBuffer(t,i,r),{address:o,signature:h}=s.signMessage(n);return this.createAttestationTransaction(t,i,o,h,r)}verifyAttestationWithAIP(t){if(!Array.isArray(t)||"0x6a"!==t[0]||t[1]!==l)throw new Error("Not a valid BAP transaction");const e="0x44415441"===t[7]?5:0,i={type:m.hexDecode(t[2]),hash:m.hexDecode(t[3]),sequence:m.hexDecode(t[4]),signingProtocol:m.hexDecode(t[7+e]),signingAddress:m.hexDecode(t[8+e]),signature:m.hexDecode(t[9+e],"base64")};e&&t[3]===t[8]&&(i.data=m.hexDecode(t[9]));try{const r=[];for(let i=0;i<6+e;i++)r.push(Buffer.from(t[i].replace("0x",""),"hex"));const s=Buffer.concat(r);i.verified=this.verifySignature(s,i.signingAddress,i.signature)}catch(t){i.verified=!1}return i}createAttestationTransaction(t,e,i,r,s=""){const n=["0x6a",m.hexEncode(y)];return n.push(m.hexEncode("ATTEST")),n.push(m.hexEncode(t)),n.push(m.hexEncode(`${e}`)),n.push("0x7c"),s&&(n.push(m.hexEncode(y)),n.push(m.hexEncode("DATA")),n.push(m.hexEncode(t)),n.push(m.hexEncode(s)),n.push("0x7c")),n.push(m.hexEncode(p)),n.push(m.hexEncode("BITCOIN_ECDSA")),n.push(m.hexEncode(i)),n.push(`0x${Buffer.from(r,"base64").toString("hex")}`),n}getAttestationBuffer(t,e=0,i=""){let r=Buffer.from("");return i&&(r=Buffer.concat([Buffer.from(y),Buffer.from("DATA"),Buffer.from(t),Buffer.from(i),Buffer.from("7c","hex")])),Buffer.concat([Buffer.from("6a","hex"),Buffer.from(y),Buffer.from("ATTEST"),Buffer.from(t),Buffer.from(`${e}`),Buffer.from("7c","hex"),r])}verifySignature(t,e,s){const n=Buffer.isBuffer(t)?t:Buffer.from(t),o=h.fromCompact(s,"base64");let a;const d=H(n.toString("hex"),"hex");for(let t=0;t<4;t++)try{if(a=o.RecoverPublicKey(t,new r(i.magicHash(d))),i.verify(d,o,a)&&a.toAddress()===e)return!0}catch(t){}return!1}async verifyChallengeSignature(t,e,i,r){if(this.verifySignature(i,e,r)){const e=await this.getApiData("/attestation/valid",{idKey:t,challenge:i,signature:r});return!!e&&e.valid}return!1}async isValidAttestationTransaction(t){return!!this.verifyAttestationWithAIP(t)&&this.getApiData("/attestation/valid",{tx:t})}async getIdentityFromAddress(t){return this.getApiData("/identity/from-address",{address:t})}async getIdentity(t){return this.getApiData("/identity/get",{idKey:t})}async getAttestationsForHash(t){return this.getApiData("/attestations",{hash:t})}}export{z as BAP,C as BAP_ID};
2
- //# sourceMappingURL=index.modern.js.map
1
+ // @bun
2
+ import{BSM as N,Utils as d,BigNumber as s,ECIES as r,HD as v,PrivateKey as g,Signature as i}from"@bsv/sdk";var P=async(j,$,q,J)=>{let Q=`${q}${j}`;return(await fetch(Q,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:J,format:"json"},body:JSON.stringify($)})).json()},M=(j,$)=>async(q,J)=>{return P(q,J,j,$)};var Y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",A=`0x${Buffer.from("1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT").toString("hex")}`,E="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",Jj=`0x${Buffer.from("15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva").toString("hex")}`,V="https://api.sigmaidentity.com/v1",F=2147483647,U="m/424150'/0'/0'",G="m/424150'/2147483647'/2147483647'";import{BSM as C,Utils as o,BigNumber as B,ECIES as y,HD as n,Hash as X,PublicKey as x}from"@bsv/sdk";import{randomBytes as h}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 h(j).toString("hex")},isHex(j){if(typeof j!=="string")return!1;return/^[0-9a-fA-F]+$/.test(j)},getSigningPathFromHex(j,$=!0){let q="m",J=j.match(/.{1,8}/g);if(!J)throw new Error("Invalid hex string");let Q=2147483647;for(let z of J){let Z=Number(`0x${z}`);if(Z>Q)Z-=Q;q+=`/${Z}${$?"'":""}`}return q},getNextIdentityPath(j){let $=j.split("/"),q=$[$.length-2],J=!1;if(q.match("'"))J=!0;let Q=(Number(q.replace(/[^0-9]/g,""))+1).toString();return $[$.length-2]=Q+(J?"'":""),$[$.length-1]=`0${J?"'":""}`,$.join("/")},getNextPath(j){let $=j.split("/"),q=$[$.length-1],J=!1;if(q.match("'"))J=!0;let Q=(Number(q.replace(/[^0-9]/g,""))+1).toString();return $[$.length-1]=Q+(J?"'":""),$.join("/")}};var{toArray:w,toHex:f,toBase58:u,toUTF8:I,toBase64:S}=o,{electrumDecrypt:m,electrumEncrypt:H}=y,{magicHash:T}=C;class R{#j;#z;#$;#q;#J;lastIdPath="";#Q;name;description;identityKey;rootAddress;identityAttributes;BAP_SERVER_;BAP_TOKEN_;getApiData;constructor(j,$={},q=""){if(this.#Q=q,this.BAP_SERVER_=V,this.BAP_TOKEN_="",this.getApiData=M(this.BAP_SERVER_,this.BAP_TOKEN_),this.name="ID 1",this.description="",j instanceof n){if(this.#j=j,q){let z=f(X.sha256(q,"utf8")),Z=W.getSigningPathFromHex(z);this.#j=j.derive(Z)}this.rootPath=`${U}/0/0/0`,this.#J=this.rootPath,this.#q=`${U}/0/0/1`;let Q=this.#j.derive(this.rootPath);this.rootAddress=Q.privKey.toPublicKey().toAddress()}else this.#z=j,this.rootAddress=j.toPublicKey().toAddress();this.identityKey=this.deriveIdentityKey(this.rootAddress);let J=JSON.parse(JSON.stringify($));this.identityAttributes=this.parseAttributes(J)}get BAP_SERVER(){return this.BAP_SERVER_}set BAP_SERVER(j){this.BAP_SERVER_=j,this.getApiData=M(this.BAP_SERVER_,this.BAP_TOKEN_)}get BAP_TOKEN(){return this.BAP_TOKEN_}set BAP_TOKEN(j){this.BAP_TOKEN_=j,this.getApiData=M(this.BAP_SERVER_,this.BAP_TOKEN_)}deriveIdentityKey(j){let $=f(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 $={},q=j.replace(/^\s+/g,"").replace(/\r/gm,"").split(`
3
+ `);for(let J of q){let z=J.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 q=this.getAttributeUrn($);if(q)j+=`${q}
4
+ `}return j}getAttributeUrn(j){let $=this.identityAttributes[j];if($)return`urn:bap:id:${j}:${$.value}:${$.nonce}`;return null}addAttribute(j,$,q=""){let J=q;if(!q)J=W.getRandomString();this.identityAttributes[j]={value:$,nonce:J}}set rootPath(j){if(this.#j){let $=j;if(j.split("/").length<5)$=`${U}${j}`;if(!this.validatePath($))throw new Error(`invalid signing path given ${$}`);this.#$=$;let q=this.#j.derive($);this.rootAddress=q.pubKey.toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress),this.#J=$,this.#q=$}}get rootPath(){if(!this.#$)throw new Error("rootPath not set");return this.#$}getRootPath(){if(!this.#$)throw new Error("rootPath not set");return this.#$}set currentPath(j){let $=j;if(j.split("/").length<5)$=`${U}${j}`;if(!this.validatePath($))throw new Error("invalid signing path given");this.#J=this.#q,this.#q=$}get currentPath(){if(!this.#q)throw new Error("currentPath not set");return this.#q}get previousPath(){if(!this.#J)throw new Error("previousPath not set");return this.#J}get idSeed(){return this.#Q}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.#q===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.#J)}getAddress(j){if(!this.#j)throw new Error("HDPrivateKey not set");return this.#j.derive(j).privKey.toPublicKey().toAddress()}getCurrentAddress(){if(!this.#q){if(!this.#z)throw new Error("currentPath not set");return this.#z.toPublicKey().toAddress()}return this.getAddress(this.#q)}getEncryptionPublicKey(){if(this.#j)return this.#j.derive(this.rootPath).derive(G).pubKey.toString();if(!this.#z)throw new Error("No private key available for encryption");return this.#z.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(j){return this.getEncryptionPrivateKeyWithSeed(j).toPublicKey().toString()}encrypt(j,$){if(!this.#j)throw new Error("HDPrivateKey not set");let J=this.#j.derive(this.rootPath).derive(G).privKey,Q=J.toPublicKey(),z=$?x.fromString($):Q;return S(H(w(j),z,J))}decrypt(j,$){if(!this.#j)throw new Error("HDPrivateKey not set");let J=this.#j.derive(this.rootPath).derive(G).privKey,Q;if($)Q=x.fromString($);return I(m(w(j,"base64"),J,Q))}encryptWithSeed(j,$,q){let J=this.getEncryptionPrivateKeyWithSeed($),Q=J.toPublicKey(),z=q?x.fromString(q):Q;return S(H(w(j),z,J))}decryptWithSeed(j,$,q){let J=this.getEncryptionPrivateKeyWithSeed($),z=J.toPublicKey();if(q)z=x.fromString(q);return I(m(w(j,"base64"),J,z))}getEncryptionPrivateKeyWithSeed(j){if(!this.#j)throw new Error("HDPrivateKey not set");if(!this.#$)throw new Error("rootPath not set");let $=f(X.sha256(j,"utf8")),q=W.getSigningPathFromHex($);return this.#j.derive(this.rootPath).derive(q).privKey}getAttestation(j){let $=X.sha256(j,"utf8");return`bap:attest:${f($)}:${this.getIdentityKey()}`}getAttestationHash(j){let $=this.getAttributeUrn(j);if(!$)return null;let q=this.getAttestation($),J=X.sha256(q,"utf8");return f(J)}signMessage(j,$=""){if(!this.#j&&!this.#z)throw new Error("No private key available");if(this.#j){if(!this.#q)throw new Error("currentPath not set");let k=$||this.#q,O=this.#j.derive(k).privKey,_=O.toPublicKey().toAddress(),c=C.sign(w(j),O,"raw"),b=new B(T(w(j,"utf8"))),l=c.CalculateRecoveryFactor(O.toPublicKey(),b),p=C.sign(w(j),O,"raw").toCompact(l,!0,"base64");return{address:_,signature:p}}let q=this.#z,J=q.toPublicKey().toAddress(),Q=C.sign(w(j),q,"raw"),z=new B(T(w(j,"utf8"))),Z=Q.CalculateRecoveryFactor(q.toPublicKey(),z),L=C.sign(w(j),q,"raw").toCompact(Z,!0,"base64");return{address:J,signature:L}}signMessageWithSeed(j,$){if(!this.#j)throw new Error("HDPrivateKey not set");if(!this.#$)throw new Error("rootPath not set");let q=f(X.sha256($,"utf8")),J=W.getSigningPathFromHex(q),z=this.#j.derive(this.#$).derive(J),Z=z.privKey.toPublicKey().toAddress(),L=C.sign(w(j),z.privKey,"raw"),k=new B(T(w(j,"utf8"))),O=L.CalculateRecoveryFactor(z.privKey.toPublicKey(),k),_=C.sign(w(Buffer.from(j)),z.privKey,"raw").toCompact(O,!0,"base64");return{address:Z,signature:_}}signOpReturnWithAIP(j,$="",q="hex"){let J=this.getAIPMessageBuffer(j),{address:Q,signature:z}=this.signMessage(J,$);return j.concat([Buffer.from("|").toString(q),Buffer.from(E).toString(q),Buffer.from("BITCOIN_ECDSA").toString(q),Buffer.from(Q).toString(q),Buffer.from(z,"base64").toString(q)])}getAIPMessageBuffer(j){let $=[];if(j[0].replace("0x","")!=="6a")$.push(Buffer.from("6a","hex"));for(let q of j)$.push(Buffer.from(q.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),q=await this.getApiData("/attestation/get",{hash:$});return console.log("getAttestations",j,$,q),q}import(j){if(this.name="name"in j&&typeof j.name==="string"?j.name:"ID 1",this.description=j.description||"",this.identityKey=j.identityKey,this.rootAddress=j.rootAddress,"rootPath"in j&&"currentPath"in j&&"previousPath"in j)this.#$=j.rootPath,this.#q=j.currentPath,this.#J=j.previousPath;this.#Q=j.idSeed||"",this.identityAttributes=this.parseAttributes(j.identityAttributes)}export(){if(this.#j){if(!this.#$||!this.#q||!this.#J)throw new Error("Required paths are not set");return{rootPath:this.#$,currentPath:this.#q,previousPath:this.#J,lastIdPath:this.lastIdPath,idSeed:this.#Q,name:this.name,description:this.description,identityKey:this.identityKey,rootAddress:this.rootAddress,identityAttributes:this.identityAttributes}}if(!this.#z)throw new Error("Neither HDPrivateKey nor singlePrivateKey is set");return{derivedPrivateKey:this.#z.toString(),idSeed:this.#Q,name:this.name,description:this.description,identityKey:this.identityKey,rootAddress:this.rootAddress,identityAttributes:this.identityAttributes}}}var{toArray:D,toUTF8:a,toBase64:e}=d,{electrumEncrypt:t,electrumDecrypt:jj}=r;class $j{#j;#z="";get lastIdPath(){return this.#z}#$={};#q=V;#J="";getApiData;constructor(j,$){if(!j)throw new Error("Key is required for BAP initialization");if(typeof j==="string")try{this.#j=v.fromString(j)}catch(q){try{this.#j=g.fromWif(j)}catch(J){throw new Error("Invalid private key format")}}else this.#j=j;if($!==void 0)this.#J=$;this.getApiData=M(this.#q,this.#J)}isHD(j){return"depth"in j&&"parentFingerPrint"in j}getPublicKey(j=""){if(this.isHD(this.#j)){if(j!=="")return this.#j.derive(j).pubKey.toString();return this.#j.pubKey.toString()}return this.#j.toPublicKey().toString()}getHdPublicKey(j=""){if(!this.isHD(this.#j))throw new Error("Not an HD key");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.#$)this.#$[$].BAP_SERVER=j}get BAP_SERVER(){return this.#q}set BAP_TOKEN(j){this.#J=j;for(let $ in this.#$)this.#$[$].BAP_TOKEN=j}get BAP_TOKEN(){return this.#J}checkIdBelongs(j){if(!this.isHD(this.#j))throw new Error("checkIdBelongs can only be used in HD mode");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.#$)}newId(j,$={},q=""){let J;if(!j)J=this.getNextValidPath();else J=j;let Q=new R(this.#j,$,q);Q.BAP_SERVER=this.#q,Q.BAP_TOKEN=this.#J,Q.rootPath=J,Q.currentPath=W.getNextPath(J);let z=Q.getIdentityKey();return this.#$[z]=Q,this.#z=J,this.#$[z]}removeId(j){delete this.#$[j]}getNextValidPath(){if(this.#z)return W.getNextIdentityPath(this.#z);return`/0'/${Object.keys(this.#$).length}'/0'`}getId(j){return this.#$[j]||null}setId(j){this.checkIdBelongs(j),this.#$[j.getIdentityKey()]=j}importIds(j,$=!0){if($&&typeof j==="string"){this.importEncryptedIds(j);return}let q=j;if(!q.lastIdPath||!Array.isArray(q.ids))throw new Error("ID data is not in the correct format");let J=!(this.#j instanceof v);if(J&&q.ids.length>1)throw new Error("Cannot import multiple IDs in single key mode");let Q=q.lastIdPath;for(let z of q.ids){if(!z.identityKey||!z.identityAttributes||!z.rootAddress)throw new Error("ID cannot be imported as it is not complete");let Z;if(qj(z)){if(!J)throw new Error("Cannot import single key identity in HD mode");let L=g.fromString(z.derivedPrivateKey,"hex");Z=new R(L,z.identityAttributes,z.idSeed)}else if(K(z)){if(J)throw new Error("Cannot import HD identity in single key mode");let L=this.#j;Z=new R(L,z.identityAttributes,z.idSeed),Z.rootPath=z.rootPath,Z.currentPath=z.currentPath}else throw new Error("Invalid identity format");if(Z.BAP_SERVER=this.#q,Z.BAP_TOKEN=this.#J,Z.import(z),!J&&K(z)){if(Q==="")Q=z.currentPath;this.checkIdBelongs(Z)}this.#$[Z.getIdentityKey()]=Z}if(!J)this.#z=Q}importEncryptedIds(j){let $=this.decrypt(j),q=JSON.parse($);if(Array.isArray(q)){console.log(`Importing old format:
5
+ `,q),this.importOldIds(q);return}if(typeof q!=="object")throw new Error("decrypted, but found unrecognized identities format");this.importIds(q,!1)}importOldIds(j){for(let $ of j){let q=new R(this.#j,{},$.idSeed??"");if(q.BAP_SERVER=this.#q,q.BAP_TOKEN=this.#J,q.import($),this.checkIdBelongs(q),this.#$[q.getIdentityKey()]=q,"currentPath"in $&&typeof $.currentPath==="string")this.#z=$.currentPath;else this.#z=""}}exportIds(j=!0,$){let q={lastIdPath:this.#z,ids:[]},J=$||Object.keys(this.#$);for(let Q of J){if(!this.#$[Q])throw new Error(`Identity ${Q} not found`);q.ids.push(this.#$[Q].export())}if(j)return this.encrypt(JSON.stringify(q));return q}encrypt(j){if(!this.isHD(this.#j))throw new Error("Encryption not supported in single key mode");let $=this.#j.derive(G);return e(t(D(j),$.pubKey))}decrypt(j){if(!this.isHD(this.#j))throw new Error("Decryption not supported in single key mode");let $=this.#j.derive(G);return a(jj(D(j,"base64"),$.privKey))}signAttestationWithAIP(j,$,q=0,J=""){let Q=this.getId($);if(!Q)throw new Error("Could not find identity to attest with");let z=this.getAttestationBuffer(j,q,J),{address:Z,signature:L}=Q.signMessage(z);return this.createAttestationTransaction(j,q,Z,L,J)}verifyAttestationWithAIP(j){if(!Array.isArray(j)||j[0]!=="0x6a"||j[1]!==A)throw new Error("Not a valid BAP transaction");let $=j[7]==="0x44415441"?5:0,q={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])q.data=W.hexDecode(j[9]);try{let J=[];for(let z=0;z<6+$;z++)J.push(Buffer.from(j[z].replace("0x",""),"hex"));let Q=Buffer.concat(J);q.verified=this.verifySignature(Q,q.signingAddress,q.signature)}catch(J){q.verified=!1}return q}createAttestationTransaction(j,$,q,J,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(E)),z.push(W.hexEncode("BITCOIN_ECDSA")),z.push(W.hexEncode(q)),z.push(`0x${Buffer.from(J,"base64").toString("hex")}`),z}getAttestationBuffer(j,$=0,q=""){let J=Buffer.from("");if(q)J=Buffer.concat([Buffer.from(Y),Buffer.from("DATA"),Buffer.from(j),Buffer.from(q),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"),J])}verifySignature(j,$,q){let J=Buffer.isBuffer(j)?j:Buffer.from(j),Q=i.fromCompact(q,"base64"),z,Z=D(J.toString("hex"),"hex");for(let L=0;L<4;L++)try{if(z=Q.RecoverPublicKey(L,new s(N.magicHash(Z))),N.verify(Z,Q,z)&&z.toAddress()===$)return!0}catch(k){}return!1}async verifyChallengeSignature(j,$,q,J){if(!this.verifySignature(q,$,J))return!1;try{let z=await this.getApiData("/attestation/valid",{idKey:j,address:$,challenge:q,signature:J});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})}}function qj(j){return"derivedPrivateKey"in j}function K(j){return"rootPath"in j&&"currentPath"in j&&"previousPath"in j}export{qj as isSingleKeyIdentity,K as isHDIdentity,R as BAP_ID,$j as BAP};
6
+
7
+ //# debugId=4036FD6C9BC6FFC664756E2164756E21