@did-btcr2/api 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.
- package/LICENSE +373 -0
- package/README.md +7 -0
- package/dist/browser.js +191676 -0
- package/dist/browser.mjs +191670 -0
- package/dist/cjs/api.js +180 -0
- package/dist/cjs/api.js.map +1 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/api.js +180 -0
- package/dist/esm/api.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types/api.d.ts +105 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +137 -0
- package/src/api.ts +302 -0
- package/src/index.ts +1 -0
package/src/api.ts
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BitcoinCoreRpcClient,
|
|
3
|
+
BitcoinRestClient,
|
|
4
|
+
BlockV3,
|
|
5
|
+
RawTransactionV2,
|
|
6
|
+
RestClientConfigParams,
|
|
7
|
+
RpcClientConfig
|
|
8
|
+
} from '@did-btcr2/bitcoin';
|
|
9
|
+
import type {
|
|
10
|
+
Bytes,
|
|
11
|
+
CryptosuiteName,
|
|
12
|
+
DocumentBytes,
|
|
13
|
+
Entropy,
|
|
14
|
+
HashBytes,
|
|
15
|
+
Hex,
|
|
16
|
+
JSONObject,
|
|
17
|
+
KeyBytes,
|
|
18
|
+
PatchOperation,
|
|
19
|
+
ProofBytes,
|
|
20
|
+
SchnorrKeyPairObject,
|
|
21
|
+
SignatureBytes
|
|
22
|
+
} from '@did-btcr2/common';
|
|
23
|
+
import { DEFAULT_BLOCK_CONFIRMATIONS, DEFAULT_REST_CONFIG, DEFAULT_RPC_CONFIG, IdentifierTypes, NotImplementedError } from '@did-btcr2/common';
|
|
24
|
+
import type { MultikeyObject } from '@did-btcr2/cryptosuite';
|
|
25
|
+
import { SchnorrMultikey } from '@did-btcr2/cryptosuite';
|
|
26
|
+
import { SchnorrKeyPair, Secp256k1SecretKey } from '@did-btcr2/keypair';
|
|
27
|
+
import type { DidCreateOptions, DidResolutionOptions, SignalsMetadata, UpdateParams } from '@did-btcr2/method';
|
|
28
|
+
import { DidBtcr2, DidDocument, DidDocumentBuilder, Identifier } from '@did-btcr2/method';
|
|
29
|
+
import type { DidResolutionResult, DidService, DidVerificationMethod } from '@web5/dids';
|
|
30
|
+
|
|
31
|
+
export { DidDocument, DidDocumentBuilder, Identifier, IdentifierTypes };
|
|
32
|
+
export type {
|
|
33
|
+
BlockV3,
|
|
34
|
+
Bytes,
|
|
35
|
+
CryptosuiteName,
|
|
36
|
+
DidResolutionResult,
|
|
37
|
+
DidService,
|
|
38
|
+
DidVerificationMethod,
|
|
39
|
+
DocumentBytes,
|
|
40
|
+
HashBytes,
|
|
41
|
+
Hex,
|
|
42
|
+
JSONObject,
|
|
43
|
+
KeyBytes,
|
|
44
|
+
MultikeyObject,
|
|
45
|
+
PatchOperation,
|
|
46
|
+
ProofBytes,
|
|
47
|
+
RawTransactionV2,
|
|
48
|
+
RestClientConfigParams,
|
|
49
|
+
RpcClientConfig,
|
|
50
|
+
SchnorrKeyPairObject,
|
|
51
|
+
SignatureBytes
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/* =========================
|
|
55
|
+
* Configuration Interfaces
|
|
56
|
+
* ========================= */
|
|
57
|
+
|
|
58
|
+
export type NetworkName = 'mainnet' | 'testnet4' | 'signet' | 'regtest';
|
|
59
|
+
|
|
60
|
+
export type BitcoinApiConfig = {
|
|
61
|
+
/** Shortcut to compute base URLs and params via @did-btcr2/bitcoin getNetwork */
|
|
62
|
+
network?: NetworkName;
|
|
63
|
+
/** Override REST client settings */
|
|
64
|
+
rest?: RestClientConfigParams;
|
|
65
|
+
/** Override RPC client settings */
|
|
66
|
+
rpc?: RpcClientConfig;
|
|
67
|
+
/** Default number of confirmations to consider "final" */
|
|
68
|
+
defaultConfirmations?: number;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type ApiConfig = {
|
|
72
|
+
bitcoin?: BitcoinApiConfig;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/* =========================
|
|
76
|
+
* Sub-facade: KeyPair
|
|
77
|
+
* ========================= */
|
|
78
|
+
|
|
79
|
+
export class KeyPairApi {
|
|
80
|
+
/** Generate a new Schnorr keypair (secp256k1). */
|
|
81
|
+
static generate(): SchnorrKeyPair {
|
|
82
|
+
return new SchnorrKeyPair();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Import from secret key bytes or bigint. */
|
|
86
|
+
static fromSecret(ent: Entropy): SchnorrKeyPair {
|
|
87
|
+
const sk = new Secp256k1SecretKey(ent);
|
|
88
|
+
return new SchnorrKeyPair({ secretKey: sk });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class MultikeyApi {
|
|
93
|
+
/**
|
|
94
|
+
* Create a Schnorr Multikey wrapper (includes verificationMethod, sign/verify).
|
|
95
|
+
* If secret is present, the multikey can sign.
|
|
96
|
+
*/
|
|
97
|
+
static create(params: {
|
|
98
|
+
id: string;
|
|
99
|
+
controller: string;
|
|
100
|
+
keys: SchnorrKeyPair
|
|
101
|
+
}): SchnorrMultikey {
|
|
102
|
+
return new SchnorrMultikey(params);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Produce a DID Verification Method JSON from a multikey. */
|
|
106
|
+
static toVerificationMethod(mk: SchnorrMultikey): DidVerificationMethod {
|
|
107
|
+
return mk.toVerificationMethod();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Sign bytes via the multikey (requires secret). */
|
|
111
|
+
static async sign(mk: SchnorrMultikey, data: Bytes): Promise<SignatureBytes> {
|
|
112
|
+
return mk.sign(data);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Verify signature via multikey. */
|
|
116
|
+
static async verify(mk: SchnorrMultikey, data: Bytes, signature: SignatureBytes): Promise<boolean> {
|
|
117
|
+
return mk.verify(data, signature);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* =========================
|
|
122
|
+
* Sub-facade: Crypto
|
|
123
|
+
* ========================= */
|
|
124
|
+
|
|
125
|
+
export class CryptoApi {
|
|
126
|
+
public static keyPairApi = new KeyPairApi();
|
|
127
|
+
public static multikeyApi = new MultikeyApi();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* =========================
|
|
131
|
+
* Sub-facade: Bitcoin
|
|
132
|
+
* ========================= */
|
|
133
|
+
|
|
134
|
+
export class BitcoinApi {
|
|
135
|
+
readonly rest: BitcoinRestClient;
|
|
136
|
+
readonly rpc: BitcoinCoreRpcClient;
|
|
137
|
+
readonly defaultConfirmations: number;
|
|
138
|
+
|
|
139
|
+
constructor(cfg?: BitcoinApiConfig) {
|
|
140
|
+
const restCfg = {
|
|
141
|
+
host : cfg?.rest?.host ?? DEFAULT_REST_CONFIG.host,
|
|
142
|
+
...cfg?.rest
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const rpcCfg = {
|
|
146
|
+
...DEFAULT_RPC_CONFIG,
|
|
147
|
+
...cfg?.rpc
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
this.rest = new BitcoinRestClient(restCfg);
|
|
151
|
+
this.rpc = new BitcoinCoreRpcClient(rpcCfg);
|
|
152
|
+
this.defaultConfirmations = cfg?.defaultConfirmations ?? DEFAULT_BLOCK_CONFIRMATIONS;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Fetch a transaction by txid via REST. */
|
|
156
|
+
async getTransaction(txid: string) {
|
|
157
|
+
return await this.rest.transaction.get(txid);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Broadcast a raw tx (hex) via REST. */
|
|
161
|
+
async send(rawTxHex: string) {
|
|
162
|
+
return await this.rest.transaction.send(rawTxHex);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Get UTXOs for an address via REST. */
|
|
166
|
+
async getUtxos(address: string) {
|
|
167
|
+
return await this.rest.address.getUtxos(address);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Get a block by hash or height via REST. */
|
|
171
|
+
async getBlock(params: { hash?: string; height?: number }) {
|
|
172
|
+
return await this.rest.block.get({ blockhash: params.hash, height: params.height });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* =========================
|
|
177
|
+
* Sub-facade: KeyManager
|
|
178
|
+
* ========================= */
|
|
179
|
+
|
|
180
|
+
// export class KeyManagerApi {
|
|
181
|
+
// readonly impl: IMethodKeyManager;
|
|
182
|
+
|
|
183
|
+
// constructor(params?: ApiKeyManagerConfig) {
|
|
184
|
+
// this.impl = new MethodKeyManager(params);
|
|
185
|
+
// }
|
|
186
|
+
|
|
187
|
+
// setActive(keyUri: string) {
|
|
188
|
+
// this.impl.activeKeyUri = keyUri;
|
|
189
|
+
// }
|
|
190
|
+
|
|
191
|
+
// export(keyUri: string) {
|
|
192
|
+
// return this.impl.export(keyUri);
|
|
193
|
+
// }
|
|
194
|
+
|
|
195
|
+
// import(mk: SchnorrMultikey, opts?: { importKey?: boolean; active?: boolean }) {
|
|
196
|
+
// return this.impl.import(mk, opts);
|
|
197
|
+
// }
|
|
198
|
+
|
|
199
|
+
// sign(keyUri: string, hash: HashBytes): Promise<SignatureBytes> {
|
|
200
|
+
// return this.impl.sign(keyUri, hash);
|
|
201
|
+
// }
|
|
202
|
+
// }
|
|
203
|
+
|
|
204
|
+
/* =========================
|
|
205
|
+
* Sub-facade: DID / CRUD
|
|
206
|
+
* ========================= */
|
|
207
|
+
|
|
208
|
+
export class DidApi {
|
|
209
|
+
/**
|
|
210
|
+
* Create a deterministic DID from a public key (bytes).
|
|
211
|
+
*/
|
|
212
|
+
async createDeterministic({ genesisBytes, options }: {
|
|
213
|
+
genesisBytes: KeyBytes;
|
|
214
|
+
options: DidCreateOptions;
|
|
215
|
+
}) {
|
|
216
|
+
return await DidBtcr2.create({ idType: 'KEY', genesisBytes, options });
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Create from an intermediate DID document (external genesis).
|
|
221
|
+
*/
|
|
222
|
+
async createExternal({ genesisBytes, options }: {
|
|
223
|
+
genesisBytes: DocumentBytes;
|
|
224
|
+
options: DidCreateOptions;
|
|
225
|
+
}) {
|
|
226
|
+
return await DidBtcr2.create({ idType: 'KEY', genesisBytes, options });
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Resolve DID document from DID (did:btcr2:...).
|
|
231
|
+
*/
|
|
232
|
+
async resolve(did: string, options: DidResolutionOptions): Promise<DidResolutionResult> {
|
|
233
|
+
return await DidBtcr2.resolve(did, options);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Update a DID Document using a JSON Patch, signed as capabilityInvocation.
|
|
238
|
+
* You provide the prior DID Document (to pick VM), a JSON Patch, and a signer multikey.
|
|
239
|
+
* This delegates to MethodUpdate (which follows the cryptosuite rules internally).
|
|
240
|
+
*/
|
|
241
|
+
async update({
|
|
242
|
+
identifier,
|
|
243
|
+
sourceDocument,
|
|
244
|
+
sourceVersionId,
|
|
245
|
+
patch,
|
|
246
|
+
verificationMethodId,
|
|
247
|
+
beaconIds
|
|
248
|
+
}: UpdateParams): Promise<SignalsMetadata> {
|
|
249
|
+
// The Update class exposes the algorithm that creates a DID Update Payload and proof;
|
|
250
|
+
// keep this wrapper narrow so testing can mock MethodUpdate directly.
|
|
251
|
+
const result = await DidBtcr2.update({
|
|
252
|
+
identifier,
|
|
253
|
+
sourceDocument,
|
|
254
|
+
sourceVersionId,
|
|
255
|
+
patch,
|
|
256
|
+
verificationMethodId,
|
|
257
|
+
beaconIds,
|
|
258
|
+
});
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Deactivate convenience: applies the standard `deactivated: true` patch. */
|
|
263
|
+
async deactivate(): Promise<SignalsMetadata> {
|
|
264
|
+
// This class is a stub in method right now; expose a narrow wrapper for future expansion.
|
|
265
|
+
// return DidBtcr2.deactivate({ identifier, patch }); // No-op holder; implement when core adds behavior.
|
|
266
|
+
throw new NotImplementedError(
|
|
267
|
+
'DidApi.deactivate is not implemented yet.',
|
|
268
|
+
{
|
|
269
|
+
type : 'DID_API_METHOD_NOT_IMPLEMENTED',
|
|
270
|
+
name : 'NOT_IMPLEMENTED_ERROR'
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* =========================
|
|
277
|
+
* Root facade
|
|
278
|
+
* ========================= */
|
|
279
|
+
|
|
280
|
+
export class DidBtcr2Api {
|
|
281
|
+
readonly bitcoin: BitcoinApi;
|
|
282
|
+
readonly did: DidApi;
|
|
283
|
+
readonly keys: KeyPairApi;
|
|
284
|
+
readonly crypto: CryptoApi;
|
|
285
|
+
// readonly keyManager: KeyManagerApi;
|
|
286
|
+
|
|
287
|
+
constructor(config?: ApiConfig) {
|
|
288
|
+
this.bitcoin = new BitcoinApi(config?.bitcoin);
|
|
289
|
+
this.did = new DidApi();
|
|
290
|
+
this.keys = new KeyPairApi();
|
|
291
|
+
this.crypto = new CryptoApi();
|
|
292
|
+
// this.keyManager = new KeyManagerApi(config?.keyManager);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* =========================
|
|
297
|
+
* Factory
|
|
298
|
+
* ========================= */
|
|
299
|
+
|
|
300
|
+
export function createApi(config?: ApiConfig) {
|
|
301
|
+
return new DidBtcr2Api(config);
|
|
302
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './api.js';
|