bsv-bap 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +10 -0
- package/dist/apiTypes.d.ts +36 -0
- package/dist/id.d.ts +5 -10
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +221 -230
- package/dist/index.modern.js +1 -1
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +1 -1
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/interface.d.ts +1 -1
- package/dist/poa.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
import { HD } from "@bsv/sdk";
|
2
1
|
import { BAP_ID } from "./id";
|
2
|
+
import { type APIFetcher } from "./api";
|
3
3
|
import type { Attestation, Identity, IdentityAttributes, PathPrefix } from "./interface";
|
4
|
+
import type { GetAttestationResponse, GetIdentityByAddressResponse } from "./apiTypes";
|
4
5
|
type Identities = {
|
5
6
|
lastIdPath: string;
|
6
7
|
ids: Identity[];
|
@@ -12,232 +13,222 @@ type Identities = {
|
|
12
13
|
*
|
13
14
|
* @param HDPrivateKey
|
14
15
|
*/
|
15
|
-
export declare
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
* Helper function to get attestation from a BAP API server
|
235
|
-
*
|
236
|
-
* @param apiUrl
|
237
|
-
* @param apiData
|
238
|
-
* @returns {Promise<any>}
|
239
|
-
*/
|
240
|
-
getApiData(apiUrl: string, apiData: any): Promise<any>;
|
241
|
-
};
|
242
|
-
};
|
243
|
-
export {};
|
16
|
+
export declare class BAP {
|
17
|
+
#private;
|
18
|
+
getApiData: APIFetcher;
|
19
|
+
constructor(HDPrivateKey: string, token?: string, server?: string);
|
20
|
+
get lastIdPath(): string;
|
21
|
+
/**
|
22
|
+
* Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty
|
23
|
+
*
|
24
|
+
* @param childPath Full derivation path for this child
|
25
|
+
* @returns {*}
|
26
|
+
*/
|
27
|
+
getPublicKey(childPath?: string): string;
|
28
|
+
/**
|
29
|
+
* Get the public key of the given childPath, or of the current HDPrivateKey of childPath is empty
|
30
|
+
*
|
31
|
+
* @param childPath Full derivation path for this child
|
32
|
+
* @returns {*}
|
33
|
+
*/
|
34
|
+
getHdPublicKey(childPath?: string): string;
|
35
|
+
set BAP_SERVER(bapServer: string);
|
36
|
+
get BAP_SERVER(): string;
|
37
|
+
set BAP_TOKEN(token: string);
|
38
|
+
get BAP_TOKEN(): string;
|
39
|
+
/**
|
40
|
+
* This function verifies that the given bapId matches the given root address
|
41
|
+
* This is used as a data integrity check
|
42
|
+
*
|
43
|
+
* @param bapId BAP_ID instance
|
44
|
+
*/
|
45
|
+
checkIdBelongs(bapId: BAP_ID): boolean;
|
46
|
+
/**
|
47
|
+
* Returns a list of all the identity keys that are stored in this instance
|
48
|
+
*
|
49
|
+
* @returns {string[]}
|
50
|
+
*/
|
51
|
+
listIds(): string[];
|
52
|
+
/**
|
53
|
+
* Create a new Id and link it to this BAP instance
|
54
|
+
*
|
55
|
+
* This function uses the length of the #ids of this class to determine the next valid path.
|
56
|
+
* If not all ids related to this HDPrivateKey have been loaded, determine the path externally
|
57
|
+
* and pass it to newId when creating a new ID.
|
58
|
+
*
|
59
|
+
* @param path
|
60
|
+
* @param identityAttributes
|
61
|
+
* @param idSeed
|
62
|
+
* @returns {*}
|
63
|
+
*/
|
64
|
+
newId(path?: string, identityAttributes?: IdentityAttributes, idSeed?: string): BAP_ID;
|
65
|
+
/**
|
66
|
+
* Remove identity
|
67
|
+
*
|
68
|
+
* @param idKey
|
69
|
+
* @returns {*}
|
70
|
+
*/
|
71
|
+
removeId(idKey: string): void;
|
72
|
+
/**
|
73
|
+
* Get the next valid path for the used HDPrivateKey and loaded #ids
|
74
|
+
*
|
75
|
+
* @returns {string}
|
76
|
+
*/
|
77
|
+
getNextValidPath(): PathPrefix;
|
78
|
+
/**
|
79
|
+
* Get a certain Id
|
80
|
+
*
|
81
|
+
* @param identityKey
|
82
|
+
* @returns {null}
|
83
|
+
*/
|
84
|
+
getId(identityKey: string): BAP_ID | null;
|
85
|
+
/**
|
86
|
+
* This function is used when manipulating ID's, adding or removing attributes etc
|
87
|
+
* First create an id through this class and then use getId to get it. Then you can add/edit or
|
88
|
+
* increment the signing path and then re-set it with this function.
|
89
|
+
*
|
90
|
+
* Note: when you getId() from this class, you will be working on the same object as this class
|
91
|
+
* has and any changes made will be propagated to the id in this class. When you call exportIds
|
92
|
+
* your new changes will also be included, without having to setId().
|
93
|
+
*
|
94
|
+
* @param bapId
|
95
|
+
*/
|
96
|
+
setId(bapId: BAP_ID): void;
|
97
|
+
/**
|
98
|
+
* This function is used to import IDs and attributes from some external storage
|
99
|
+
*
|
100
|
+
* The ID information should NOT be stored together with the HD private key !
|
101
|
+
*
|
102
|
+
* @param idData Array of ids that have been exported
|
103
|
+
* @param encrypted Whether the data should be treated as being encrypted (default true)
|
104
|
+
*/
|
105
|
+
importIds(idData: Identities | string, encrypted?: boolean): void;
|
106
|
+
importEncryptedIds(idData: string): void;
|
107
|
+
importOldIds(idData: Identity[]): void;
|
108
|
+
/**
|
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 {[]|*}
|
115
|
+
*/
|
116
|
+
exportIds(encrypted: true): string;
|
117
|
+
exportIds(encrypted: false): Identities;
|
118
|
+
exportIds(encrypted?: boolean): Identities | string;
|
119
|
+
/**
|
120
|
+
* Encrypt a string of data
|
121
|
+
*
|
122
|
+
* @param string
|
123
|
+
* @returns {string}
|
124
|
+
*/
|
125
|
+
encrypt(string: string): string;
|
126
|
+
/**
|
127
|
+
* Decrypt a string of data
|
128
|
+
*
|
129
|
+
* @param string
|
130
|
+
* @returns {string}
|
131
|
+
*/
|
132
|
+
decrypt(string: string): string;
|
133
|
+
/**
|
134
|
+
* Sign an attestation for a user
|
135
|
+
*
|
136
|
+
* @param attestationHash The computed attestation hash for the user - this should be calculated with the BAP_ID class for an identity for the user
|
137
|
+
* @param identityKey The identity key we are using for the signing
|
138
|
+
* @param counter
|
139
|
+
* @param dataString Optional data string that will be appended to the BAP attestation
|
140
|
+
* @returns {string[]}
|
141
|
+
*/
|
142
|
+
signAttestationWithAIP(attestationHash: string, identityKey: string, counter?: number, dataString?: string): string[];
|
143
|
+
/**
|
144
|
+
* Verify an AIP signed attestation for a user
|
145
|
+
*
|
146
|
+
* [
|
147
|
+
* '0x6a',
|
148
|
+
* '0x31424150537561506e66476e53424d33474c56397968785564596534764762644d54',
|
149
|
+
* '0x415454455354',
|
150
|
+
* '0x33656166366361396334313936356538353831366439336439643034333136393032376633396661623034386333633031333663343364663635376462383761',
|
151
|
+
* '0x30',
|
152
|
+
* '0x7c',
|
153
|
+
* '0x313550636948473232534e4c514a584d6f5355615756693757537163376843667661',
|
154
|
+
* '0x424954434f494e5f4543445341',
|
155
|
+
* '0x31477531796d52567a595557634638776f6f506a7a4a4c764d383550795a64655876',
|
156
|
+
* '0x20ef60c5555001ddb1039bb0f215e46571fcb39ee46f48b089d1c08b0304dbcb3366d8fdf8bafd82be24b5ac42dcd6a5e96c90705dd42e3ad918b1b47ac3ce6ac2'
|
157
|
+
* ]
|
158
|
+
*
|
159
|
+
* @param tx Array of hex values for the OP_RETURN values
|
160
|
+
* @returns {{}}
|
161
|
+
*/
|
162
|
+
verifyAttestationWithAIP(tx: string[]): Attestation;
|
163
|
+
/**
|
164
|
+
* For BAP attestations we use all fields for the attestation
|
165
|
+
*
|
166
|
+
* @param attestationHash
|
167
|
+
* @param counter
|
168
|
+
* @param address
|
169
|
+
* @param signature
|
170
|
+
* @param dataString Optional data string that will be appended to the BAP attestation
|
171
|
+
* @returns {[string]}
|
172
|
+
*/
|
173
|
+
createAttestationTransaction(attestationHash: string, counter: number, address: string, signature: string, dataString?: string): string[];
|
174
|
+
/**
|
175
|
+
* This is a re-creation of how the bitcoinfiles-sdk creates a hash to sign for AIP
|
176
|
+
*
|
177
|
+
* @param attestationHash
|
178
|
+
* @param counter
|
179
|
+
* @param dataString Optional data string
|
180
|
+
* @returns {Buffer}
|
181
|
+
*/
|
182
|
+
getAttestationBuffer(attestationHash: string, counter?: number, dataString?: string): Buffer;
|
183
|
+
/**
|
184
|
+
* Verify that the identity challenge is signed by the address
|
185
|
+
*
|
186
|
+
* @param message Buffer or utf-8 string
|
187
|
+
* @param address Bitcoin address of signee
|
188
|
+
* @param signature Signature base64 string
|
189
|
+
*
|
190
|
+
* @return boolean
|
191
|
+
*/
|
192
|
+
verifySignature(message: string | Buffer, address: string, signature: string): boolean;
|
193
|
+
/**
|
194
|
+
* Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the
|
195
|
+
* identity signing is also valid at the time of signing
|
196
|
+
*
|
197
|
+
* @param idKey
|
198
|
+
* @param address
|
199
|
+
* @param challenge
|
200
|
+
* @param signature
|
201
|
+
*
|
202
|
+
* @returns {Promise<boolean|*>}
|
203
|
+
*/
|
204
|
+
verifyChallengeSignature(idKey: string, address: string, challenge: string, signature: string): Promise<boolean>;
|
205
|
+
/**
|
206
|
+
* Check whether the given transaction (BAP OP_RETURN) is valid, is signed and that the
|
207
|
+
* identity signing is also valid at the time of signing
|
208
|
+
*
|
209
|
+
* @param tx
|
210
|
+
* @returns {Promise<boolean|*>}
|
211
|
+
*/
|
212
|
+
isValidAttestationTransaction(tx: string[]): Promise<any>;
|
213
|
+
/**
|
214
|
+
* Get all signing keys for the given idKey
|
215
|
+
*
|
216
|
+
* @param address
|
217
|
+
* @returns {Promise<*>}
|
218
|
+
*/
|
219
|
+
getIdentityFromAddress(address: string): Promise<GetIdentityByAddressResponse>;
|
220
|
+
/**
|
221
|
+
* Get all signing keys for the given idKey
|
222
|
+
*
|
223
|
+
* @param idKey
|
224
|
+
* @returns {Promise<*>}
|
225
|
+
*/
|
226
|
+
getIdentity(idKey: string): Promise<any>;
|
227
|
+
/**
|
228
|
+
* Get all attestations for the given attestation hash
|
229
|
+
*
|
230
|
+
* @param attestationHash
|
231
|
+
*/
|
232
|
+
getAttestationsForHash(attestationHash: string): Promise<GetAttestationResponse>;
|
233
|
+
}
|
234
|
+
export { BAP_ID };
|
package/dist/index.modern.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import{Hash as t,PublicKey as e,BSM as r,BigNumber as i,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 r=arguments[e];for(var i in r)({}).hasOwnProperty.call(r,i)&&(t[i]=r[i])}return t},f.apply(null,arguments)}const g={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 r="m";const i=t.match(/.{1,8}/g);if(!i)throw new Error("Invalid hex string");const s=2147483647;for(const t of i){let i=Number(`0x${t}`);i>s&&(i-=s),r+=`/${i}${e?"'":""}`}return r},getNextIdentityPath(t){const e=t.split("/"),r=e[e.length-2];let i=!1;r.match("'")&&(i=!0);const s=(Number(r.replace(/[^0-9]/g,""))+1).toString();return e[e.length-2]=s+(i?"'":""),e[e.length-1]="0"+(i?"'":""),e.join("/")},getNextPath(t){const e=t.split("/"),r=e[e.length-1];let i=!1;r.match("'")&&(i=!0);const s=(Number(r.replace(/[^0-9]/g,""))+1).toString();return e[e.length-1]=s+(i?"'":""),e.join("/")}},y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",l=`0x${Buffer.from(y).toString("hex")}`,p="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva";Buffer.from(p).toString("hex");const A="https://api.sigmaidentity.com/api/v1",b=2147483647,v="m/424150'/0'/0'",P="m/424150'/2147483647'/2147483647'",{toArray:m,toHex:S,toBase58:B,toUTF8:x,toBase64:K}=s,{electrumDecrypt:E,electrumEncrypt:I}=n,{magicHash:w}=r;var O,N,D,T,$,j=/*#__PURE__*/c("HDPrivateKey"),R=/*#__PURE__*/c("BAP_SERVER"),_=/*#__PURE__*/c("BAP_TOKEN"),C=/*#__PURE__*/c("rootPath"),H=/*#__PURE__*/c("previousPath"),V=/*#__PURE__*/c("currentPath"),W=/*#__PURE__*/c("idSeed");class k{constructor(e,r={},i=""){if(Object.defineProperty(this,j,{writable:!0,value:void 0}),Object.defineProperty(this,R,{writable:!0,value:A}),Object.defineProperty(this,_,{writable:!0,value:""}),Object.defineProperty(this,C,{writable:!0,value:void 0}),Object.defineProperty(this,H,{writable:!0,value:void 0}),Object.defineProperty(this,V,{writable:!0,value:void 0}),Object.defineProperty(this,W,{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,d(this,W)[W]=i,i){const r=S(t.sha256(i,"utf8")),s=g.getSigningPathFromHex(r);d(this,j)[j]=e.derive(s)}else d(this,j)[j]=e;this.idName="ID 1",this.description="",d(this,C)[C]=`${v}/0/0/0`,d(this,H)[H]=`${v}/0/0/0`,d(this,V)[V]=`${v}/0/0/1`;const s=d(this,j)[j].derive(d(this,C)[C]);this.rootAddress=s.privKey.toPublicKey().toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress);const n=f({},r);this.identityAttributes=this.parseAttributes(n)}set BAP_SERVER(t){d(this,R)[R]=t}get BAP_SERVER(){return d(this,R)[R]}set BAP_TOKEN(t){d(this,_)[_]=t}get BAP_TOKEN(){return d(this,_)[_]}deriveIdentityKey(e){const r=S(t.sha256(e,"utf8"));return B(t.ripemd160(r,"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={},r=t.replace(/^\s+/g,"").replace(/\r/gm,"").split("\n");for(const t of r){const r=t.replace(/^\s+/g,"").replace(/\s+$/g,"").split(":");"urn"===r[0]&&"bap"===r[1]&&"id"===r[2]&&r[3]&&r[4]&&r[5]&&(e[r[3]]={value:r[4],nonce:r[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 r=this.getAttributeUrn(e);r&&(t+=`${r}\n`)}return t}getAttributeUrn(t){const e=this.identityAttributes[t];return e?`urn:bap:id:${t}:${e.value}:${e.nonce}`:null}addAttribute(t,e,r=""){let i=r;r||(i=g.getRandomString()),this.identityAttributes[t]={value:e,nonce:i}}set rootPath(t){if(d(this,j)[j]){let e=t;if(t.split("/").length<5&&(e=`${v}${t}`),!this.validatePath(e))throw new Error(`invalid signing path given ${e}`);d(this,C)[C]=e;const r=d(this,j)[j].derive(e);this.rootAddress=r.pubKey.toAddress(),this.identityKey=this.deriveIdentityKey(this.rootAddress),d(this,H)[H]=e,d(this,V)[V]=e}}get rootPath(){return d(this,C)[C]}getRootPath(){return d(this,C)[C]}set currentPath(t){let e=t;if(t.split("/").length<5&&(e=`${v}${t}`),!this.validatePath(e))throw new Error("invalid signing path given");d(this,H)[H]=d(this,V)[V],d(this,V)[V]=e}get currentPath(){return d(this,V)[V]}get previousPath(){return d(this,H)[H]}get idSeed(){return d(this,W)[W]}incrementPath(){this.currentPath=g.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("'",""))<=b&&Number(e[2].replace("'",""))<=b&&Number(e[3].replace("'",""))<=b&&Number(e[4].replace("'",""))<=b&&Number(e[5].replace("'",""))<=b&&Number(e[6].replace("'",""))<=b)return!0}return!1}getInitialIdTransaction(){return this.getIdTransaction(d(this,C)[C])}getIdTransaction(t=""){if(d(this,V)[V]===d(this,C)[C])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,H)[H])}getAddress(t){return d(this,j)[j].derive(t).privKey.toPublicKey().toAddress()}getCurrentAddress(){return this.getAddress(d(this,V)[V])}getEncryptionPublicKey(){return d(this,j)[j].derive(d(this,C)[C]).derive(P).privKey.toPublicKey().toString()}getEncryptionPublicKeyWithSeed(t){return this.getEncryptionPrivateKeyWithSeed(t).toPublicKey().toString("hex")}encrypt(t,r){const i=d(this,j)[j].derive(d(this,C)[C]).derive(P).privKey.toPublicKey(),s=r?e.fromString(r):i;return K(I(m(t),s,null))}decrypt(t,r){const i=d(this,j)[j].derive(d(this,C)[C]).derive(P).privKey;let s;return r&&(s=e.fromString(r)),x(E(m(t,"base64"),i,s))}encryptWithSeed(t,r,i){const s=this.getEncryptionPrivateKeyWithSeed(r),n=s.toPublicKey(),o=i?e.fromString(i):n;return K(I(m(t),o,s))}decryptWithSeed(t,r,i){const s=this.getEncryptionPrivateKeyWithSeed(r);let n;return i&&(n=e.fromString(i)),x(E(m(t,"base64"),s,n))}getEncryptionPrivateKeyWithSeed(e){const r=S(t.sha256(e,"utf8")),i=g.getSigningPathFromHex(r);return d(this,j)[j].derive(d(this,C)[C]).derive(i).privKey}getAttestation(e){const r=t.sha256(e,"utf8");return`bap:attest:${S(r)}:${this.getIdentityKey()}`}getAttestationHash(e){const r=this.getAttributeUrn(e);if(!r)return null;const i=this.getAttestation(r),s=t.sha256(i,"utf8");return S(s)}signMessage(t,e=""){let s;s=t instanceof Buffer?t:Buffer.from(t);const n=e||d(this,V)[V],o=d(this,j)[j].derive(n).privKey,h=o.toAddress(),a=r.sign(m(t),o),u=new i(w(m(t,"utf8"))),c=a.CalculateRecoveryFactor(o.toPublicKey(),u);return{address:h,signature:r.sign(m(s),o).toCompact(c,!0,"base64")}}signMessageWithSeed(e,s){const n=S(t.sha256(s,"utf8")),o=g.getSigningPathFromHex(n),h=d(this,j)[j].derive(d(this,C)[C]).derive(o),a=h.privKey.toPublicKey().toAddress(),u=r.sign(m(e),h.privKey),c=new i(w(m(e,"utf8"))),f=u.CalculateRecoveryFactor(h.privKey.toPublicKey(),c);return{address:a,signature:r.sign(m(Buffer.from(e)),h.privKey).toCompact(f,!0,"base64")}}signOpReturnWithAIP(t,e="",r="hex"){const i=this.getAIPMessageBuffer(t),{address:s,signature:n}=this.signMessage(i,e);return t.concat([Buffer.from("|").toString(r),Buffer.from(p).toString(r),Buffer.from("BITCOIN_ECDSA").toString(r),Buffer.from(s).toString(r),Buffer.from(n,"base64").toString(r)])}getAIPMessageBuffer(t){const e=[];"6a"!==t[0].replace("0x","")&&e.push(Buffer.from("6a","hex"));for(const r of t)e.push(Buffer.from(r.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),r=await this.getApiData("/attestations",{hash:e});return console.log("getAttestations",t,e,r),r}async getApiData(t,e){const r=`${d(this,R)[R]}${t}`;return(await fetch(r,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:d(this,_)[_],format:"json"},body:JSON.stringify(e)})).json()}import(t){this.idName=t.name,this.description=t.description||"",this.identityKey=t.identityKey,d(this,C)[C]=t.rootPath,this.rootAddress=t.rootAddress,d(this,H)[H]=t.previousPath,d(this,V)[V]=t.currentPath,d(this,W)[W]=t.idSeed||"",this.identityAttributes=this.parseAttributes(t.identityAttributes)}export(){return{name:this.idName,description:this.description,identityKey:this.identityKey,rootPath:d(this,C)[C],rootAddress:this.rootAddress,previousPath:d(this,H)[H],currentPath:d(this,V)[V],idSeed:d(this,W)[W],identityAttributes:this.getAttributes(),lastIdPath:""}}}const{toArray:F,toUTF8:U,toBase64:M}=s,{electrumEncrypt:J,electrumDecrypt:G}=n,q=(O=/*#__PURE__*/c("HDPrivateKey"),N=/*#__PURE__*/c("ids"),D=/*#__PURE__*/c("BAP_SERVER"),T=/*#__PURE__*/c("BAP_TOKEN"),$=/*#__PURE__*/c("lastIdPath"),class{constructor(t,e=""){if(Object.defineProperty(this,O,{writable:!0,value:void 0}),Object.defineProperty(this,N,{writable:!0,value:{}}),Object.defineProperty(this,D,{writable:!0,value:A}),Object.defineProperty(this,T,{writable:!0,value:""}),Object.defineProperty(this,$,{writable:!0,value:""}),!t)throw new Error("No HDPrivateKey given");d(this,O)[O]=o.fromString(t),e&&(d(this,T)[T]=e)}get lastIdPath(){return d(this,$)[$]}getPublicKey(t=""){return t?d(this,O)[O].derive(t).pubKey.toString():d(this,O)[O].pubKey.toString()}getHdPublicKey(t=""){return t?d(this,O)[O].derive(t).toPublic().toString():d(this,O)[O].toPublic().toString()}set BAP_SERVER(t){d(this,D)[D]=t;for(const e of Object.keys(d(this,N)[N]))d(this,N)[N][e].BAP_SERVER=t}get BAP_SERVER(){return d(this,D)[D]}set BAP_TOKEN(t){d(this,T)[T]=t;for(const e of Object.keys(d(this,N)[N]))d(this,N)[N][e].BAP_TOKEN=t}get BAP_TOKEN(){return d(this,T)[T]}checkIdBelongs(t){if(d(this,O)[O].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,N)[N])}newId(t,e={},r=""){let i;i=t||this.getNextValidPath();const s=new k(d(this,O)[O],e,r);s.BAP_SERVER=d(this,D)[D],s.BAP_TOKEN=d(this,T)[T],s.rootPath=i,s.currentPath=g.getNextPath(i);const n=s.getIdentityKey();return d(this,N)[N][n]=s,d(this,$)[$]=i,d(this,N)[N][n]}removeId(t){delete d(this,N)[N][t]}getNextValidPath(){return d(this,$)[$]?g.getNextIdentityPath(d(this,$)[$]):`/0'/${Object.keys(d(this,N)[N]).length}'/0'`}getId(t){return d(this,N)[N][t]||null}setId(t){this.checkIdBelongs(t),d(this,N)[N][t.getIdentityKey()]=t}importIds(t,e=!0){if(e&&"string"==typeof t)return void this.importEncryptedIds(t);const r=t;if(!r.lastIdPath)throw new Error("ID cannot be imported as it is not complete");if(!r.ids)throw new Error(`ID data is not in the correct format: ${t}`);let i=t.lastIdPath;for(const t of r.ids){if(!t.identityKey||!t.identityAttributes||!t.rootAddress)throw new Error("ID cannot be imported as it is not complete");const e=new k(d(this,O)[O],{},t.idSeed);e.BAP_SERVER=d(this,D)[D],e.BAP_TOKEN=d(this,T)[T],e.import(t),""===i&&(i=e.currentPath),this.checkIdBelongs(e),d(this,N)[N][e.getIdentityKey()]=e}d(this,$)[$]=i}importEncryptedIds(t){const e=this.decrypt(t),r=JSON.parse(e);if(Array.isArray(r))return console.log("Importing old format:\n",r),void this.importOldIds(r);if("object"!=typeof r)throw new Error("decrypted, but found unrecognized identities format");this.importIds(r,!1)}importOldIds(t){for(const e of t){const t=new k(d(this,O)[O],{},e.idSeed);t.BAP_SERVER=d(this,D)[D],t.BAP_TOKEN=d(this,T)[T],t.import(e),this.checkIdBelongs(t),d(this,N)[N][t.getIdentityKey()]=t,d(this,$)[$]=t.currentPath}}exportIds(t=!0){const e={lastIdPath:d(this,$)[$],ids:[]};for(const t of Object.keys(d(this,N)[N]))e.ids.push(d(this,N)[N][t].export());return t?this.encrypt(JSON.stringify(e)):e}encrypt(t){const e=d(this,O)[O].derive(P);return M(J(F(t),e.pubKey,null))}decrypt(t){const e=d(this,O)[O].derive(P);return U(G(F(t,"base64"),e.privKey))}signAttestationWithAIP(t,e,r=0,i=""){const s=this.getId(e);if(!s)throw new Error("Could not find identity to attest with");const n=this.getAttestationBuffer(t,r,i),{address:o,signature:h}=s.signMessage(n);return this.createAttestationTransaction(t,r,o,h,i)}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,r={type:g.hexDecode(t[2]),hash:g.hexDecode(t[3]),sequence:g.hexDecode(t[4]),signingProtocol:g.hexDecode(t[7+e]),signingAddress:g.hexDecode(t[8+e]),signature:g.hexDecode(t[9+e],"base64")};e&&t[3]===t[8]&&(r.data=g.hexDecode(t[9]));try{const i=[];for(let r=0;r<6+e;r++)i.push(Buffer.from(t[r].replace("0x",""),"hex"));const s=Buffer.concat([...i]);r.verified=this.verifySignature(s,r.signingAddress,r.signature)}catch(t){r.verified=!1}return r}createAttestationTransaction(t,e,r,i,s=""){const n=["0x6a",g.hexEncode(y)];return n.push(g.hexEncode("ATTEST")),n.push(g.hexEncode(t)),n.push(g.hexEncode(`${e}`)),n.push("0x7c"),s&&(n.push(g.hexEncode(y)),n.push(g.hexEncode("DATA")),n.push(g.hexEncode(t)),n.push(g.hexEncode(s)),n.push("0x7c")),n.push(g.hexEncode(p)),n.push(g.hexEncode("BITCOIN_ECDSA")),n.push(g.hexEncode(r)),n.push(`0x${Buffer.from(i,"base64").toString("hex")}`),n}getAttestationBuffer(t,e=0,r=""){let i=Buffer.from("");return r&&(i=Buffer.concat([Buffer.from(y),Buffer.from("DATA"),Buffer.from(t),Buffer.from(r),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"),i])}verifySignature(t,e,s){const n=Buffer.isBuffer(t)?t:Buffer.from(t),o=h.fromCompact(s,"base64");let a;const d=F(n.toString("hex"),"hex");for(let t=0;t<4;t++)try{if(a=o.RecoverPublicKey(t,new i(r.magicHash(d))),r.verify(d,o,a)&&a.toAddress()===e)return!0}catch(t){}return!1}async verifyChallengeSignature(t,e,r,i){return!!this.verifySignature(r,e,i)&&(await this.getApiData("/attestation/valid",{idKey:t,challenge:r,signature:i})).data}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",{idKey:t})}async getAttestationsForHash(t){return this.getApiData("/attestations",{hash:t})}async getApiData(t,e){const r=`${d(this,D)[D]}${t}`;return(await fetch(r,{method:"post",headers:{"Content-type":"application/json; charset=utf-8",token:d(this,T)[T],format:"json"},body:JSON.stringify(e)})).json()}});export{q as BAP};
|
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={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("/")}},y="1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT",l=`0x${Buffer.from(y).toString("hex")}`,p="15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva";Buffer.from(p).toString("hex");const A="https://api.sigmaidentity.com/api/v1",v=2147483647,b="m/424150'/0'/0'",P="m/424150'/2147483647'/2147483647'",m=(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),{toArray:S,toHex:B,toBase58:x,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=B(t.sha256(r,"utf8")),s=g.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]=`${b}/0/0/0`,d(this,$)[$]=`${b}/0/0/0`,d(this,_)[_]=`${b}/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=m(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=B(t.sha256(e,"utf8"));return x(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=g.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=`${b}${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=`${b}${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=g.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(P).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(P).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(P).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=B(t.sha256(e,"utf8")),r=g.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:${B(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 B(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),u=new r(N(S(t,"utf8"))),c=a.CalculateRecoveryFactor(o.toPublicKey(),u);return{address:h,signature:i.sign(S(s),o).toCompact(c,!0,"base64")}}signMessageWithSeed(e,s){const n=B(t.sha256(s,"utf8")),o=g.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),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).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"),G=/*#__PURE__*/c("BAP_SERVER"),J=/*#__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,G,{writable:!0,value:A}),Object.defineProperty(this,J,{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,J)[J]=e),i&&(d(this,G)[G]=i),this.getApiData=m(d(this,G)[G],d(this,J)[J])}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,G)[G]=t;for(const e in d(this,M)[M])d(this,M)[M][e].BAP_SERVER=t}get BAP_SERVER(){return d(this,G)[G]}set BAP_TOKEN(t){d(this,J)[J]=t;for(const e in d(this,M)[M])d(this,M)[M][e].BAP_TOKEN=t}get BAP_TOKEN(){return d(this,J)[J]}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,G)[G],s.BAP_TOKEN=d(this,J)[J],s.rootPath=r,s.currentPath=g.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]?g.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,G)[G],e.BAP_TOKEN=d(this,J)[J],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,G)[G],t.BAP_TOKEN=d(this,J)[J],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}encrypt(t){const e=d(this,k)[k].derive(P);return W(F(H(t),e.pubKey,null))}decrypt(t){const e=d(this,k)[k].derive(P);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:g.hexDecode(t[2]),hash:g.hexDecode(t[3]),sequence:g.hexDecode(t[4]),signingProtocol:g.hexDecode(t[7+e]),signingAddress:g.hexDecode(t[8+e]),signature:g.hexDecode(t[9+e],"base64")};e&&t[3]===t[8]&&(i.data=g.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",g.hexEncode(y)];return n.push(g.hexEncode("ATTEST")),n.push(g.hexEncode(t)),n.push(g.hexEncode(`${e}`)),n.push("0x7c"),s&&(n.push(g.hexEncode(y)),n.push(g.hexEncode("DATA")),n.push(g.hexEncode(t)),n.push(g.hexEncode(s)),n.push("0x7c")),n.push(g.hexEncode(p)),n.push(g.hexEncode("BITCOIN_ECDSA")),n.push(g.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",{idKey:t})}async getAttestationsForHash(t){return this.getApiData("/attestations",{hash:t})}}export{z as BAP,C as BAP_ID};
|
2
2
|
//# sourceMappingURL=index.modern.js.map
|