@europeum-ebsi/cli 0.0.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.txt +289 -0
- package/README.md +98 -0
- package/bin/cli.js +13 -0
- package/dist/abi/pilot/DidRegistry.js +568 -0
- package/dist/abi/pilot/DidRegistry.js.map +1 -0
- package/dist/abi/pilot/Ptr.js +666 -0
- package/dist/abi/pilot/Ptr.js.map +1 -0
- package/dist/abi/pilot/SchemaSCRegistry.js +264 -0
- package/dist/abi/pilot/SchemaSCRegistry.js.map +1 -0
- package/dist/abi/pilot/Tcr.js +715 -0
- package/dist/abi/pilot/Tcr.js.map +1 -0
- package/dist/abi/pilot/Timestamp.js +658 -0
- package/dist/abi/pilot/Timestamp.js.map +1 -0
- package/dist/abi/pilot/Tir.js +428 -0
- package/dist/abi/pilot/Tir.js.map +1 -0
- package/dist/abi/pilot/TnT.js +842 -0
- package/dist/abi/pilot/TnT.js.map +1 -0
- package/dist/abi/pilot/Tpr.js +492 -0
- package/dist/abi/pilot/Tpr.js.map +1 -0
- package/dist/abi/test/DidRegistry.js +568 -0
- package/dist/abi/test/DidRegistry.js.map +1 -0
- package/dist/abi/test/Ptr.js +666 -0
- package/dist/abi/test/Ptr.js.map +1 -0
- package/dist/abi/test/SchemaSCRegistry.js +300 -0
- package/dist/abi/test/SchemaSCRegistry.js.map +1 -0
- package/dist/abi/test/Tcr.js +715 -0
- package/dist/abi/test/Tcr.js.map +1 -0
- package/dist/abi/test/Timestamp.js +658 -0
- package/dist/abi/test/Timestamp.js.map +1 -0
- package/dist/abi/test/Tir.js +428 -0
- package/dist/abi/test/Tir.js.map +1 -0
- package/dist/abi/test/TnT.js +842 -0
- package/dist/abi/test/TnT.js.map +1 -0
- package/dist/abi/test/Tpr.js +492 -0
- package/dist/abi/test/Tpr.js.map +1 -0
- package/dist/app.js +659 -0
- package/dist/app.js.map +1 -0
- package/dist/buildParam/didr.js +374 -0
- package/dist/buildParam/didr.js.map +1 -0
- package/dist/buildParam/index.js +53 -0
- package/dist/buildParam/index.js.map +1 -0
- package/dist/buildParam/ptr.js +80 -0
- package/dist/buildParam/ptr.js.map +1 -0
- package/dist/buildParam/tcr.js +36 -0
- package/dist/buildParam/tcr.js.map +1 -0
- package/dist/buildParam/timestamp.js +350 -0
- package/dist/buildParam/timestamp.js.map +1 -0
- package/dist/buildParam/tir.js +110 -0
- package/dist/buildParam/tir.js.map +1 -0
- package/dist/buildParam/tnt.js +214 -0
- package/dist/buildParam/tnt.js.map +1 -0
- package/dist/buildParam/tpr.js +91 -0
- package/dist/buildParam/tpr.js.map +1 -0
- package/dist/buildParam/tsr.js +115 -0
- package/dist/buildParam/tsr.js.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/authorisation.js +144 -0
- package/dist/commands/authorisation.js.map +1 -0
- package/dist/commands/compute.js +680 -0
- package/dist/commands/compute.js.map +1 -0
- package/dist/commands/conformance.js +813 -0
- package/dist/commands/conformance.js.map +1 -0
- package/dist/commands/hardwarewallet.js +41 -0
- package/dist/commands/hardwarewallet.js.map +1 -0
- package/dist/commands/index.js +8 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/ledger.js +397 -0
- package/dist/commands/ledger.js.map +1 -0
- package/dist/commands/ptr.js +54 -0
- package/dist/commands/ptr.js.map +1 -0
- package/dist/commands/tcr.js +50 -0
- package/dist/commands/tcr.js.map +1 -0
- package/dist/commands/tir.js +64 -0
- package/dist/commands/tir.js.map +1 -0
- package/dist/commands/tnl.js +81 -0
- package/dist/commands/tnl.js.map +1 -0
- package/dist/commands/tsr.js +45 -0
- package/dist/commands/tsr.js.map +1 -0
- package/dist/commands/view.js +53 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/config.js +497 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/context.js +2 -0
- package/dist/interfaces/context.js.map +1 -0
- package/dist/interfaces/contracts/ProxyFactory.js +2 -0
- package/dist/interfaces/contracts/ProxyFactory.js.map +1 -0
- package/dist/interfaces/contracts/ProxyTemplateRegistry.js +2 -0
- package/dist/interfaces/contracts/ProxyTemplateRegistry.js.map +1 -0
- package/dist/interfaces/contracts/SchemaSCRegistry.js +2 -0
- package/dist/interfaces/contracts/SchemaSCRegistry.js.map +1 -0
- package/dist/interfaces/contracts/common.js +2 -0
- package/dist/interfaces/contracts/common.js.map +1 -0
- package/dist/interfaces/index.js +5 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/jsonrpc.interface.js +2 -0
- package/dist/interfaces/jsonrpc.interface.js.map +1 -0
- package/dist/interfaces/paginated-list.interface.js +2 -0
- package/dist/interfaces/paginated-list.interface.js.map +1 -0
- package/dist/interfaces/unsigned-transaction.interface.js +2 -0
- package/dist/interfaces/unsigned-transaction.interface.js.map +1 -0
- package/dist/interfaces/utils.interface.js +2 -0
- package/dist/interfaces/utils.interface.js.map +1 -0
- package/dist/programs/migrateDid.js +159 -0
- package/dist/programs/migrateDid.js.map +1 -0
- package/dist/programs/migrateDids.js +232 -0
- package/dist/programs/migrateDids.js.map +1 -0
- package/dist/programs/migrateTsr.js +201 -0
- package/dist/programs/migrateTsr.js.map +1 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step1 +34 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step2 +18 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step3 +9 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step4 +27 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step5 +13 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step6 +14 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step7 +7 -0
- package/dist/scripts/accreditAndAuthorize/test/step1 +34 -0
- package/dist/scripts/accreditAndAuthorize/test/step2 +18 -0
- package/dist/scripts/accreditAndAuthorize/test/step3 +9 -0
- package/dist/scripts/accreditAndAuthorize/test/step4 +27 -0
- package/dist/scripts/accreditAndAuthorize/test/step5 +13 -0
- package/dist/scripts/accreditAndAuthorize/test/step6 +14 -0
- package/dist/scripts/accreditAndAuthorize/test/step7 +7 -0
- package/dist/scripts/accreditTI +21 -0
- package/dist/scripts/assets/Nodes.json +27 -0
- package/dist/scripts/assets/vcdm1.1/CTRevocableCredential.json +30 -0
- package/dist/scripts/assets/vcdm1.1/CredentialToAttestVerifiableAuthorisationForTrustChain.json +29 -0
- package/dist/scripts/assets/vcdm1.1/Nodes.json +27 -0
- package/dist/scripts/assets/vcdm1.1/TrustedNodesList.json +35 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAccreditationToAccredit.json +35 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAccreditationToAttest.json +33 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationForTrustChain.json +22 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationToInvoke.json +24 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationToOnboard.json +24 -0
- package/dist/scripts/assets/vcdm2.0/CredentialToAttestVerifiableAuthorisationForTrustChain.json +29 -0
- package/dist/scripts/assets/vcdm2.0/TrustedNodesList.json +36 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAccreditationToAccredit.json +40 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAccreditationToAttest.json +38 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationForTrustChain.json +30 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationToInvoke.json +24 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationToOnboard.json +23 -0
- package/dist/scripts/bootstrap/0a-loadTPROperator +5 -0
- package/dist/scripts/bootstrap/0b-loadAdmin +8 -0
- package/dist/scripts/bootstrap/1-populateTPR +92 -0
- package/dist/scripts/bootstrap/2-populateDID +6 -0
- package/dist/scripts/bootstrap/3-populateTimestamp +9 -0
- package/dist/scripts/bootstrap/4-populateTIR +8 -0
- package/dist/scripts/bootstrap/5-populateTSR +85 -0
- package/dist/scripts/bootstrap/6-setupConformanceIssuer +35 -0
- package/dist/scripts/bootstrap/README.md +218 -0
- package/dist/scripts/issueVcInvoke +10 -0
- package/dist/scripts/issueVcOnboard +9 -0
- package/dist/scripts/issueVcRootTAO +11 -0
- package/dist/scripts/issueVcTAO +12 -0
- package/dist/scripts/issueVcTI +12 -0
- package/dist/scripts/issueVcTnl +32 -0
- package/dist/scripts/issue_CTRevocableCredential +12 -0
- package/dist/scripts/issue_SelfAttestationSupportOffice +10 -0
- package/dist/scripts/issue_VerifiableAccreditationToAccredit +11 -0
- package/dist/scripts/issue_VerifiableAccreditationToAttest +11 -0
- package/dist/scripts/issue_VerifiableAuthorisationForTrustChain +10 -0
- package/dist/scripts/issue_VerifiableAuthorisationToOnboard +9 -0
- package/dist/scripts/preregisterIssuer +6 -0
- package/dist/scripts/registerDidDocument +15 -0
- package/dist/scripts/registerIssuer +6 -0
- package/dist/scripts/updateVcRootTAO +10 -0
- package/dist/scripts/updateVcTAO +11 -0
- package/dist/scripts/updateVcTI +11 -0
- package/dist/scripts/vcdm2.0/issueSelfAttestationSupportOffice +10 -0
- package/dist/scripts/vcdm2.0/issueVcInvoke +12 -0
- package/dist/scripts/vcdm2.0/issueVcOnboard +11 -0
- package/dist/scripts/vcdm2.0/issueVcRootTAO +14 -0
- package/dist/scripts/vcdm2.0/issueVcTAO +15 -0
- package/dist/scripts/vcdm2.0/issueVcTI +15 -0
- package/dist/scripts/vcdm2.0/issueVcTnl +34 -0
- package/dist/scripts/vcdm2.0/registerDidDocument +15 -0
- package/dist/scripts/vcdm2.0/updateVcRootTAO +13 -0
- package/dist/scripts/vcdm2.0/updateVcTAO +14 -0
- package/dist/scripts/vcdm2.0/updateVcTI +14 -0
- package/dist/scripts/vcdm2.0/verifyVcTnl +10 -0
- package/dist/scripts/verifyVcTnl +10 -0
- package/dist/scripts/wct/accreditAndAuthorize +133 -0
- package/dist/scripts/wct/accreditAndAuthorize2 +89 -0
- package/dist/scripts/wct/holderWallet +39 -0
- package/dist/scripts/wct/holderWallet2 +39 -0
- package/dist/scripts/wct/issueToHolder +38 -0
- package/dist/scripts/wct/issueToHolder2 +38 -0
- package/dist/scripts/wct/pda1 +3 -0
- package/dist/scripts/wct/verifier +8 -0
- package/dist/scripts/wct/verifier2 +7 -0
- package/dist/utils/Client.js +155 -0
- package/dist/utils/Client.js.map +1 -0
- package/dist/utils/HardwareWallet.js +326 -0
- package/dist/utils/HardwareWallet.js.map +1 -0
- package/dist/utils/http.js +132 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/jsonrpc.js +38 -0
- package/dist/utils/jsonrpc.js.map +1 -0
- package/dist/utils/print.js +56 -0
- package/dist/utils/print.js.map +1 -0
- package/dist/utils/utils.js +427 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/utils/vcdm.js +47 -0
- package/dist/utils/vcdm.js.map +1 -0
- package/package.json +121 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
import { decodeJWT } from "@europeum-ebsi/did-jwt";
|
|
2
|
+
import { util } from "@europeum-ebsi/ebsi-did-resolver";
|
|
3
|
+
import { ValidationError } from "@europeum-ebsi/verifiable-credential";
|
|
4
|
+
import * as vcdm11vc from "@europeum-ebsi/verifiable-credential/vcdm11.js";
|
|
5
|
+
import * as vcdm20vc from "@europeum-ebsi/verifiable-credential/vcdm20.js";
|
|
6
|
+
import * as vcdm11vp from "@europeum-ebsi/verifiable-presentation/vcdm11.js";
|
|
7
|
+
import * as vcdm20vp from "@europeum-ebsi/verifiable-presentation/vcdm20.js";
|
|
8
|
+
import { EbsiWallet } from "@europeum-ebsi/wallet-lib";
|
|
9
|
+
import { ethers } from "ethers";
|
|
10
|
+
import Joi from "joi";
|
|
11
|
+
import { base64url, calculateJwkThumbprint } from "jose";
|
|
12
|
+
import { sha256 as hasher } from "multiformats/hashes/sha2";
|
|
13
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
14
|
+
import { computeSchemaId, encodePrivateKey, encodePublicKey, estimateVcdmVersion, formatEthersUnsignedTransaction, fromHexString, JoiHexadecimal, multibaseEncode, prefixWith0x, red, removePrefix0x, yellow, } from "../utils/index.js";
|
|
15
|
+
import { ledgerGetTransaction, ledgerGetTransactionReceipt } from "./ledger.js";
|
|
16
|
+
export async function compute(method, inputs, context) {
|
|
17
|
+
const { client } = context;
|
|
18
|
+
switch (method) {
|
|
19
|
+
case "address": {
|
|
20
|
+
const [hexOrJwk] = inputs;
|
|
21
|
+
const publicKeyHex = typeof hexOrJwk === "string"
|
|
22
|
+
? hexOrJwk
|
|
23
|
+
: encodePublicKey({
|
|
24
|
+
format: "hex",
|
|
25
|
+
key: hexOrJwk,
|
|
26
|
+
});
|
|
27
|
+
const address = ethers.computeAddress(publicKeyHex);
|
|
28
|
+
yellow(address);
|
|
29
|
+
return address;
|
|
30
|
+
}
|
|
31
|
+
case "checkStatusList2021CredentialSchema": {
|
|
32
|
+
const [credential] = inputs;
|
|
33
|
+
try {
|
|
34
|
+
Joi.assert(credential, Joi.object({
|
|
35
|
+
"@context": Joi.array()
|
|
36
|
+
.ordered(Joi.string()
|
|
37
|
+
.valid("https://www.w3.org/2018/credentials/v1")
|
|
38
|
+
.required(), Joi.string()
|
|
39
|
+
.valid("https://w3id.org/vc/status-list/2021/v1")
|
|
40
|
+
.required())
|
|
41
|
+
.items(Joi.string().uri())
|
|
42
|
+
.required(),
|
|
43
|
+
credentialSubject: Joi.object({
|
|
44
|
+
encodedList: Joi.string().required(),
|
|
45
|
+
id: Joi.string().uri().required(),
|
|
46
|
+
statusPurpose: Joi.string()
|
|
47
|
+
.valid("revocation", "suspension")
|
|
48
|
+
.required(),
|
|
49
|
+
type: Joi.string().valid("StatusList2021").required(),
|
|
50
|
+
})
|
|
51
|
+
.unknown(true)
|
|
52
|
+
.required(),
|
|
53
|
+
type: Joi.array()
|
|
54
|
+
.ordered(
|
|
55
|
+
// First item must be "VerifiableCredential"
|
|
56
|
+
Joi.string().valid("VerifiableCredential").required())
|
|
57
|
+
.items(
|
|
58
|
+
// "StatusList2021Credential" must be present
|
|
59
|
+
Joi.string().valid("StatusList2021Credential").required(), Joi.string())
|
|
60
|
+
.required(),
|
|
61
|
+
})
|
|
62
|
+
// Allow additional properties
|
|
63
|
+
.unknown(true));
|
|
64
|
+
yellow("StatusList2021 Credential Schema correct");
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
red(error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
case "verifyVcJwt": {
|
|
73
|
+
try {
|
|
74
|
+
const result = await computeVerifyVcJwt(inputs, context);
|
|
75
|
+
yellow(result);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error instanceof ValidationError) {
|
|
80
|
+
red(error.toJSON());
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
red(error);
|
|
84
|
+
}
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
case "verifyVpJwt": {
|
|
89
|
+
try {
|
|
90
|
+
const result = await computeVerifyVpJwt(inputs, context);
|
|
91
|
+
yellow(result);
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error instanceof ValidationError) {
|
|
96
|
+
red(error.toJSON());
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
red(error);
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
case "did2": {
|
|
105
|
+
const [jwk] = inputs;
|
|
106
|
+
const did = EbsiWallet.createDid("NATURAL_PERSON", jwk);
|
|
107
|
+
yellow(did);
|
|
108
|
+
return did;
|
|
109
|
+
}
|
|
110
|
+
case "createVcJwt": {
|
|
111
|
+
const payloadVc = inputs[0];
|
|
112
|
+
const payloadJwt = inputs[1];
|
|
113
|
+
const alg = (inputs[2] ?? "ES256K");
|
|
114
|
+
const vcdmVersionInput = (inputs[3] ?? "1.1");
|
|
115
|
+
Joi.assert(alg, Joi.string().valid("ES256K", "ES256", "RS256", "EdDSA").required());
|
|
116
|
+
let vcdmVersion;
|
|
117
|
+
if (vcdmVersionInput === 1.1)
|
|
118
|
+
vcdmVersion = "1.1";
|
|
119
|
+
else if (vcdmVersionInput === 2)
|
|
120
|
+
vcdmVersion = "2.0";
|
|
121
|
+
else
|
|
122
|
+
vcdmVersion = vcdmVersionInput;
|
|
123
|
+
Joi.assert(vcdmVersion, Joi.string().valid("1.1", "2.0").required());
|
|
124
|
+
const iat = Math.floor(Date.now() / 1000) - 10;
|
|
125
|
+
const exp = iat + 5 * 365 * 24 * 3600;
|
|
126
|
+
const issuanceDate = `${new Date(iat * 1000)
|
|
127
|
+
.toISOString()
|
|
128
|
+
.slice(0, -5)}Z`;
|
|
129
|
+
const expirationDate = `${new Date(exp * 1000)
|
|
130
|
+
.toISOString()
|
|
131
|
+
.slice(0, -5)}Z`;
|
|
132
|
+
const jti = payloadVc.id ?? `urn:uuid:${randomUUID()}`;
|
|
133
|
+
const sub = payloadVc.credentialSubject?.id;
|
|
134
|
+
const payload = vcdmVersion === "1.1"
|
|
135
|
+
? {
|
|
136
|
+
exp,
|
|
137
|
+
iat,
|
|
138
|
+
iss: client.did,
|
|
139
|
+
jti,
|
|
140
|
+
nbf: iat,
|
|
141
|
+
sub,
|
|
142
|
+
vc: {
|
|
143
|
+
"@context": ["https://www.w3.org/2018/credentials/v1"],
|
|
144
|
+
expirationDate,
|
|
145
|
+
id: jti,
|
|
146
|
+
issuanceDate,
|
|
147
|
+
issued: issuanceDate,
|
|
148
|
+
issuer: client.did,
|
|
149
|
+
type: ["VerifiableCredential"],
|
|
150
|
+
validFrom: issuanceDate,
|
|
151
|
+
...payloadVc,
|
|
152
|
+
},
|
|
153
|
+
...payloadJwt,
|
|
154
|
+
}
|
|
155
|
+
: {
|
|
156
|
+
"@context": ["https://www.w3.org/ns/credentials/v2"],
|
|
157
|
+
exp,
|
|
158
|
+
iat,
|
|
159
|
+
id: jti,
|
|
160
|
+
issuer: client.did,
|
|
161
|
+
type: ["VerifiableCredential"],
|
|
162
|
+
validFrom: issuanceDate,
|
|
163
|
+
validUntil: expirationDate,
|
|
164
|
+
...payloadVc,
|
|
165
|
+
...payloadJwt,
|
|
166
|
+
};
|
|
167
|
+
const vc = await client.signJWT(payload, { typ: vcdmVersion === "1.1" ? "JWT" : "vc+jwt" }, alg);
|
|
168
|
+
yellow(vc);
|
|
169
|
+
return vc;
|
|
170
|
+
}
|
|
171
|
+
case "createVpJwt": {
|
|
172
|
+
const inputVerifiableCredential = inputs[0];
|
|
173
|
+
const payloadVp = inputs[1];
|
|
174
|
+
const payloadJwt = inputs[2];
|
|
175
|
+
const alg = inputs[3] || "ES256K";
|
|
176
|
+
const vcdmVersionInput = (inputs[4] ?? "1.1");
|
|
177
|
+
let vcdmVersion;
|
|
178
|
+
if (vcdmVersionInput === 1.1)
|
|
179
|
+
vcdmVersion = "1.1";
|
|
180
|
+
else if (vcdmVersionInput === 2)
|
|
181
|
+
vcdmVersion = "2.0";
|
|
182
|
+
else
|
|
183
|
+
vcdmVersion = vcdmVersionInput;
|
|
184
|
+
Joi.assert(vcdmVersion, Joi.string().valid("1.1", "2.0").required());
|
|
185
|
+
// NOTE: We cannot use @europeum-ebsi/verifiable-presentation library
|
|
186
|
+
// because it requires the private key and the CLI tool
|
|
187
|
+
// now supports Hardware Wallets, which do not expose private keys.
|
|
188
|
+
const now = Math.floor(Date.now() / 1000) - 10;
|
|
189
|
+
const jti = `urn:did:${randomUUID()}`;
|
|
190
|
+
const payload = vcdmVersion === "1.1"
|
|
191
|
+
? {
|
|
192
|
+
aud: "any",
|
|
193
|
+
exp: now + 120, // 2 minutes in the future
|
|
194
|
+
iat: now,
|
|
195
|
+
iss: client.did,
|
|
196
|
+
jti,
|
|
197
|
+
nbf: now,
|
|
198
|
+
nonce: randomUUID(),
|
|
199
|
+
sub: client.did,
|
|
200
|
+
vp: {
|
|
201
|
+
"@context": ["https://www.w3.org/2018/credentials/v1"],
|
|
202
|
+
holder: client.did,
|
|
203
|
+
id: jti,
|
|
204
|
+
type: ["VerifiablePresentation"],
|
|
205
|
+
verifiableCredential: typeof inputVerifiableCredential === "string"
|
|
206
|
+
? [inputVerifiableCredential]
|
|
207
|
+
: inputVerifiableCredential,
|
|
208
|
+
...payloadVp,
|
|
209
|
+
},
|
|
210
|
+
...payloadJwt,
|
|
211
|
+
}
|
|
212
|
+
: {
|
|
213
|
+
"@context": ["https://www.w3.org/ns/credentials/v2"],
|
|
214
|
+
aud: "any",
|
|
215
|
+
exp: now + 120, // 2 minutes in the future
|
|
216
|
+
holder: client.did,
|
|
217
|
+
iat: now,
|
|
218
|
+
id: jti,
|
|
219
|
+
nonce: randomUUID(),
|
|
220
|
+
type: ["VerifiablePresentation"],
|
|
221
|
+
verifiableCredential: (typeof inputVerifiableCredential ===
|
|
222
|
+
"string"
|
|
223
|
+
? [inputVerifiableCredential]
|
|
224
|
+
: inputVerifiableCredential).map((vc) => ({
|
|
225
|
+
"@context": "https://www.w3.org/ns/credentials/v2",
|
|
226
|
+
id: `data:application/vc+jwt,${vc}`,
|
|
227
|
+
type: "EnvelopedVerifiableCredential",
|
|
228
|
+
})),
|
|
229
|
+
...payloadVp,
|
|
230
|
+
...payloadJwt,
|
|
231
|
+
};
|
|
232
|
+
const vp = await client.signJWT(payload, { typ: vcdmVersion === "1.1" ? "JWT" : "vp+jwt" }, alg);
|
|
233
|
+
yellow(vp);
|
|
234
|
+
return vp;
|
|
235
|
+
}
|
|
236
|
+
case "decodeBase64": {
|
|
237
|
+
const enc = inputs[0];
|
|
238
|
+
const type = inputs[1] || "utf8";
|
|
239
|
+
Joi.assert(enc, Joi.string());
|
|
240
|
+
const buffer = Buffer.from(enc, "base64");
|
|
241
|
+
if (type === "buffer") {
|
|
242
|
+
console.log(buffer);
|
|
243
|
+
return buffer;
|
|
244
|
+
}
|
|
245
|
+
if (type === "json") {
|
|
246
|
+
const decoded = JSON.parse(buffer.toString("utf8"));
|
|
247
|
+
yellow(decoded);
|
|
248
|
+
return decoded;
|
|
249
|
+
}
|
|
250
|
+
const decoded = buffer.toString("utf8");
|
|
251
|
+
yellow(decoded);
|
|
252
|
+
return decoded;
|
|
253
|
+
}
|
|
254
|
+
case "decodeBase64url": {
|
|
255
|
+
const enc = inputs[0];
|
|
256
|
+
Joi.assert(enc, Joi.string());
|
|
257
|
+
const decoded = base64url.decode(enc);
|
|
258
|
+
yellow(decoded);
|
|
259
|
+
return decoded;
|
|
260
|
+
}
|
|
261
|
+
case "decodeContractData": {
|
|
262
|
+
const [types, dataInput, hasFn] = inputs;
|
|
263
|
+
Joi.assert(types, Joi.array().items(Joi.string()));
|
|
264
|
+
Joi.assert(dataInput, JoiHexadecimal);
|
|
265
|
+
Joi.assert(hasFn, Joi.string().valid("true", "false").optional());
|
|
266
|
+
let fn;
|
|
267
|
+
let data;
|
|
268
|
+
if (hasFn === "true") {
|
|
269
|
+
fn = `0x${removePrefix0x(dataInput).slice(0, 8)}`;
|
|
270
|
+
data = `0x${removePrefix0x(dataInput).slice(8)}`;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
data = dataInput;
|
|
274
|
+
}
|
|
275
|
+
const decoded = ethers.AbiCoder.defaultAbiCoder().decode(types, data);
|
|
276
|
+
const result = {
|
|
277
|
+
data: decoded,
|
|
278
|
+
...(hasFn === "true" && { functionSig: fn }),
|
|
279
|
+
};
|
|
280
|
+
yellow(result);
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
case "decodeHex": {
|
|
284
|
+
const enc = inputs[0];
|
|
285
|
+
Joi.assert(enc, Joi.string());
|
|
286
|
+
const decoded = Buffer.from(removePrefix0x(enc), "hex").toString("utf8");
|
|
287
|
+
yellow(decoded);
|
|
288
|
+
return decoded;
|
|
289
|
+
}
|
|
290
|
+
case "decodeJWT": {
|
|
291
|
+
const jwt = inputs[0];
|
|
292
|
+
Joi.assert(jwt, Joi.string());
|
|
293
|
+
const decoded = decodeJWT(jwt);
|
|
294
|
+
yellow(decoded);
|
|
295
|
+
return decoded;
|
|
296
|
+
}
|
|
297
|
+
case "decodeLogs": {
|
|
298
|
+
const logs = inputs[0];
|
|
299
|
+
const logsDecoded = await decodeLogs(logs, context);
|
|
300
|
+
yellow(logsDecoded);
|
|
301
|
+
return logsDecoded;
|
|
302
|
+
}
|
|
303
|
+
case "decodeTransaction": {
|
|
304
|
+
const tx = inputs[0];
|
|
305
|
+
const txDecoded = await decodeTransaction(tx, context);
|
|
306
|
+
yellow(txDecoded);
|
|
307
|
+
return txDecoded;
|
|
308
|
+
}
|
|
309
|
+
case "encodeBase64": {
|
|
310
|
+
const dec = inputs[0];
|
|
311
|
+
Joi.assert(dec, Joi.string());
|
|
312
|
+
const encoded = Buffer.from(removePrefix0x(dec), "hex").toString("base64");
|
|
313
|
+
yellow(encoded);
|
|
314
|
+
return encoded;
|
|
315
|
+
}
|
|
316
|
+
case "encodeBase64url": {
|
|
317
|
+
const dec = inputs[0];
|
|
318
|
+
Joi.assert(dec, Joi.string());
|
|
319
|
+
const encoded = base64url.encode(Buffer.from(removePrefix0x(dec), "hex"));
|
|
320
|
+
yellow(encoded);
|
|
321
|
+
return encoded;
|
|
322
|
+
}
|
|
323
|
+
case "encodeContractData": {
|
|
324
|
+
const [types, data, fn] = inputs;
|
|
325
|
+
Joi.assert(data, Joi.array().items(Joi.string()));
|
|
326
|
+
Joi.assert(types, Joi.array().items(Joi.string()));
|
|
327
|
+
Joi.assert(fn, Joi.string().optional());
|
|
328
|
+
const encoded = ethers.AbiCoder.defaultAbiCoder().encode(types, data);
|
|
329
|
+
let result = encoded;
|
|
330
|
+
if (fn) {
|
|
331
|
+
// get the function hash
|
|
332
|
+
const fnHash = /^(?:0x)?[0-9a-fA-F]+$/.test(fn)
|
|
333
|
+
? fn
|
|
334
|
+
: ethers.keccak256(Buffer.from(fn)).slice(0, 10);
|
|
335
|
+
// prefix the function hash with the encoded data
|
|
336
|
+
result = `${prefixWith0x(fnHash)}${encoded.slice(2)}`;
|
|
337
|
+
}
|
|
338
|
+
yellow(result);
|
|
339
|
+
return result;
|
|
340
|
+
}
|
|
341
|
+
case "encodePrivateKey": {
|
|
342
|
+
const [key, options] = inputs;
|
|
343
|
+
Joi.assert(options, Joi.object({
|
|
344
|
+
alg: Joi.string()
|
|
345
|
+
.valid("ES256K", "ES256", "RS256", "EdDSA")
|
|
346
|
+
.optional(),
|
|
347
|
+
format: Joi.string().valid("jwk", "hex", "pem"),
|
|
348
|
+
type: Joi.string().valid("pkcs1", "pkcs8", "sec1", "spki").optional(),
|
|
349
|
+
}));
|
|
350
|
+
const result = encodePrivateKey({ key, ...options });
|
|
351
|
+
yellow(result);
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
case "encodePublicKey": {
|
|
355
|
+
const [key, options] = inputs;
|
|
356
|
+
Joi.assert(options, Joi.object({
|
|
357
|
+
alg: Joi.string()
|
|
358
|
+
.valid("ES256K", "ES256", "RS256", "EdDSA")
|
|
359
|
+
.optional(),
|
|
360
|
+
format: Joi.string().valid("jwk", "hex", "pem"),
|
|
361
|
+
}));
|
|
362
|
+
const result = encodePublicKey({ key, ...options });
|
|
363
|
+
yellow(result);
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
case "epochtime": {
|
|
367
|
+
let result;
|
|
368
|
+
if (!inputs[0])
|
|
369
|
+
result = Math.round(Date.now() / 1000);
|
|
370
|
+
else if (typeof inputs[0] === "string")
|
|
371
|
+
result = Math.round(new Date(inputs[0]).getTime() / 1000);
|
|
372
|
+
else
|
|
373
|
+
result = new Date(inputs[0] * 1000).toISOString();
|
|
374
|
+
yellow(result);
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
case "length": {
|
|
378
|
+
const [array] = inputs;
|
|
379
|
+
Joi.assert(array, Joi.array());
|
|
380
|
+
const len = array.length;
|
|
381
|
+
yellow(len);
|
|
382
|
+
return len;
|
|
383
|
+
}
|
|
384
|
+
case "randomID": {
|
|
385
|
+
return randomBytes(32).toString("hex");
|
|
386
|
+
}
|
|
387
|
+
case "recordId": {
|
|
388
|
+
const [address, blockNumber, hashValue] = inputs;
|
|
389
|
+
Joi.assert(inputs, Joi.array().items(Joi.string()).length(3));
|
|
390
|
+
const abiEncoded = ethers.AbiCoder.defaultAbiCoder().encode(["address", "uint256", "bytes"], [address, blockNumber, hashValue]);
|
|
391
|
+
const bufferSha256 = Buffer.from(sha256(abiEncoded), "hex");
|
|
392
|
+
const recordId = multibaseEncode("base64url", bufferSha256);
|
|
393
|
+
yellow(recordId);
|
|
394
|
+
return recordId;
|
|
395
|
+
}
|
|
396
|
+
case "schemaId": {
|
|
397
|
+
const [schema, base] = inputs;
|
|
398
|
+
const schemaId = await computeSchemaId(schema, base);
|
|
399
|
+
yellow(schemaId);
|
|
400
|
+
return schemaId;
|
|
401
|
+
}
|
|
402
|
+
case "sha256": {
|
|
403
|
+
const [data] = inputs;
|
|
404
|
+
if (typeof data === "object") {
|
|
405
|
+
return sha256(JSON.stringify(data));
|
|
406
|
+
}
|
|
407
|
+
return sha256(data);
|
|
408
|
+
}
|
|
409
|
+
case "signJwt": {
|
|
410
|
+
const [payload, alg, headers] = inputs;
|
|
411
|
+
const jwt = await client.signJWT(payload, headers, alg);
|
|
412
|
+
yellow(jwt);
|
|
413
|
+
return jwt;
|
|
414
|
+
}
|
|
415
|
+
case "signTransaction": {
|
|
416
|
+
const unsignedTransaction = inputs[0];
|
|
417
|
+
const uTx = formatEthersUnsignedTransaction(
|
|
418
|
+
// eslint-disable-next-line unicorn/prefer-structured-clone
|
|
419
|
+
JSON.parse(JSON.stringify(unsignedTransaction)));
|
|
420
|
+
const sgnTx = await client.ethWallet.signTransaction(uTx);
|
|
421
|
+
yellow(sgnTx);
|
|
422
|
+
return sgnTx;
|
|
423
|
+
}
|
|
424
|
+
case "statusListIndex": {
|
|
425
|
+
const [did] = inputs;
|
|
426
|
+
Joi.assert(did, Joi.string());
|
|
427
|
+
const statusListIndex = (createHash("sha256")
|
|
428
|
+
.update(did, "utf8")
|
|
429
|
+
.digest()
|
|
430
|
+
.slice(0, 6)
|
|
431
|
+
.readUInt32BE() % 131_072).toString();
|
|
432
|
+
yellow(statusListIndex);
|
|
433
|
+
return statusListIndex;
|
|
434
|
+
}
|
|
435
|
+
case "subaccountDid": {
|
|
436
|
+
const [did] = inputs;
|
|
437
|
+
Joi.assert(did, Joi.string());
|
|
438
|
+
const subaccountMsiBytes = createHash("sha256")
|
|
439
|
+
.update(did, "utf8")
|
|
440
|
+
.digest()
|
|
441
|
+
.slice(0, 16);
|
|
442
|
+
const subaccount = util.createDid(subaccountMsiBytes);
|
|
443
|
+
yellow(subaccount);
|
|
444
|
+
return subaccount;
|
|
445
|
+
}
|
|
446
|
+
case "thumbprint": {
|
|
447
|
+
const [hexOrJwk, alg] = inputs;
|
|
448
|
+
const publicKeyJwk = typeof hexOrJwk === "string"
|
|
449
|
+
? encodePublicKey({
|
|
450
|
+
alg,
|
|
451
|
+
format: "jwk",
|
|
452
|
+
key: hexOrJwk,
|
|
453
|
+
})
|
|
454
|
+
: hexOrJwk;
|
|
455
|
+
const thumbprint = await calculateJwkThumbprint(publicKeyJwk, "sha256");
|
|
456
|
+
yellow(thumbprint);
|
|
457
|
+
return thumbprint;
|
|
458
|
+
}
|
|
459
|
+
case "timestampId": {
|
|
460
|
+
const hash = inputs[0];
|
|
461
|
+
Joi.assert(hash, Joi.string());
|
|
462
|
+
const multihash = await hasher.digest(fromHexString(hash));
|
|
463
|
+
const timestampId = `u${base64url.encode(multihash.bytes)}`;
|
|
464
|
+
yellow(timestampId);
|
|
465
|
+
return timestampId;
|
|
466
|
+
}
|
|
467
|
+
case "userPin": {
|
|
468
|
+
const [did] = inputs;
|
|
469
|
+
const userPin = getUserPin(did);
|
|
470
|
+
yellow(userPin);
|
|
471
|
+
return userPin;
|
|
472
|
+
}
|
|
473
|
+
case "wait": {
|
|
474
|
+
const [seconds] = inputs;
|
|
475
|
+
const milliseconds = Math.round(Number(seconds) * 1000);
|
|
476
|
+
console.log(`waiting ${milliseconds / 1000} seconds`);
|
|
477
|
+
await new Promise((r) => {
|
|
478
|
+
setTimeout(r, milliseconds);
|
|
479
|
+
});
|
|
480
|
+
return 0;
|
|
481
|
+
}
|
|
482
|
+
default: {
|
|
483
|
+
throw new Error(`Invalid method '${method}'`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
export async function computeVerifyVcJwt(inputs, context) {
|
|
488
|
+
const [vcJwt, options, expectedResult] = inputs;
|
|
489
|
+
const vcdmVersion = estimateVcdmVersion(vcJwt);
|
|
490
|
+
const ebsiEnvConfig = {
|
|
491
|
+
hosts: [context.config.domain.replace(/^https?:\/\//, "")],
|
|
492
|
+
network: {
|
|
493
|
+
isOptional: false,
|
|
494
|
+
name: context.config.env,
|
|
495
|
+
},
|
|
496
|
+
scheme: "ebsi",
|
|
497
|
+
services: {
|
|
498
|
+
"did-registry": context.config.api.did.version,
|
|
499
|
+
"trusted-issuers-registry": context.config.api.tir.version,
|
|
500
|
+
"trusted-policies-registry": context.config.api.tpr.version,
|
|
501
|
+
"trusted-schemas-registry": context.config.api.tsr.version,
|
|
502
|
+
},
|
|
503
|
+
};
|
|
504
|
+
try {
|
|
505
|
+
await (vcdmVersion === "1.1" ? vcdm11vc : vcdm20vc).verifyCredentialJwt(vcJwt, ebsiEnvConfig, options);
|
|
506
|
+
switch (expectedResult) {
|
|
507
|
+
case "expectRevoked": {
|
|
508
|
+
throw new Error("Credential is not revoked");
|
|
509
|
+
}
|
|
510
|
+
default: {
|
|
511
|
+
return "Verifiable Credential is valid";
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
if (expectedResult === "expectRevoked") {
|
|
517
|
+
if (error.message === "Credential is not revoked")
|
|
518
|
+
throw error;
|
|
519
|
+
if (error.message.includes("revoked")) {
|
|
520
|
+
return "Verifiable Credential is revoked";
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
throw error;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
export async function computeVerifyVpJwt(inputs, context) {
|
|
527
|
+
const [vpJwt, audience, options] = inputs;
|
|
528
|
+
const vcdmVersion = estimateVcdmVersion(vpJwt);
|
|
529
|
+
const ebsiEnvConfig = {
|
|
530
|
+
hosts: [context.config.domain.replace(/^https?:\/\//, "")],
|
|
531
|
+
network: {
|
|
532
|
+
isOptional: false,
|
|
533
|
+
name: context.config.env,
|
|
534
|
+
},
|
|
535
|
+
scheme: "ebsi",
|
|
536
|
+
services: {
|
|
537
|
+
"did-registry": context.config.api.did.version,
|
|
538
|
+
"trusted-issuers-registry": context.config.api.tir.version,
|
|
539
|
+
"trusted-policies-registry": context.config.api.tpr.version,
|
|
540
|
+
"trusted-schemas-registry": context.config.api.tsr.version,
|
|
541
|
+
},
|
|
542
|
+
};
|
|
543
|
+
await (vcdmVersion === "1.1" ? vcdm11vp : vcdm20vp).verifyPresentationJwt(vpJwt, audience, ebsiEnvConfig, options);
|
|
544
|
+
return "Verifiable Presentation is valid";
|
|
545
|
+
}
|
|
546
|
+
export function decodeLog(log, context) {
|
|
547
|
+
const api = getApiByContractId(log.address, context);
|
|
548
|
+
const logDecoded = api.contract.interface.parseLog(log);
|
|
549
|
+
if (!logDecoded)
|
|
550
|
+
throw new Error("Can't parse log");
|
|
551
|
+
const { args: argsWithArray, fragment, name, signature, topic } = logDecoded;
|
|
552
|
+
const args = getProperties(argsWithArray, fragment.inputs);
|
|
553
|
+
return { args, name, signature, topic };
|
|
554
|
+
}
|
|
555
|
+
export async function decodeLogs(input, context) {
|
|
556
|
+
if (!input)
|
|
557
|
+
throw new Error("Invalid logs: no input provided");
|
|
558
|
+
let receipt;
|
|
559
|
+
if (typeof input === "string") {
|
|
560
|
+
receipt = await ledgerGetTransactionReceipt([input], false, context);
|
|
561
|
+
}
|
|
562
|
+
else if (input.receipt) {
|
|
563
|
+
receipt = input.receipt;
|
|
564
|
+
}
|
|
565
|
+
else if (input.logs) {
|
|
566
|
+
receipt = input;
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
if (!Array.isArray(input)) {
|
|
570
|
+
throw new TypeError("Invalid logs: The input must be a transaction hash, a transaction receipt, or an array of logs");
|
|
571
|
+
}
|
|
572
|
+
return input.map((log) => decodeLog(log, context));
|
|
573
|
+
}
|
|
574
|
+
if (!Array.isArray(receipt.logs)) {
|
|
575
|
+
throw new TypeError("Invalid logs: The input must be a transaction hash, a transaction receipt, or an array of logs");
|
|
576
|
+
}
|
|
577
|
+
return receipt.logs.map((log) => decodeLog(log, context));
|
|
578
|
+
}
|
|
579
|
+
export async function decodeTransaction(tx, context) {
|
|
580
|
+
let txData;
|
|
581
|
+
if (typeof tx === "string") {
|
|
582
|
+
txData =
|
|
583
|
+
tx.length <= 66
|
|
584
|
+
? // it is a tx hash
|
|
585
|
+
(await ledgerGetTransaction([tx], false, context))
|
|
586
|
+
: // it is a signed transaction
|
|
587
|
+
ethers.Transaction.from(tx);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
txData = tx;
|
|
591
|
+
}
|
|
592
|
+
if (!txData["data"] && !txData["input"]) {
|
|
593
|
+
throw new Error("Invalid transaction: There is no input or data");
|
|
594
|
+
}
|
|
595
|
+
const api = getApiByContractId(txData["to"], context);
|
|
596
|
+
const parsedTx = api.contract.interface.parseTransaction({
|
|
597
|
+
data: (txData["data"] ?? txData["input"]),
|
|
598
|
+
});
|
|
599
|
+
if (!parsedTx)
|
|
600
|
+
throw new Error("Can't parse transaction");
|
|
601
|
+
const { args, fragment } = parsedTx;
|
|
602
|
+
return {
|
|
603
|
+
dataDecoded: {
|
|
604
|
+
args: getProperties(args, fragment.inputs),
|
|
605
|
+
name: fragment.name,
|
|
606
|
+
},
|
|
607
|
+
tx: txData,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
export function getApiByContractId(contractId, context) {
|
|
611
|
+
const apiName = Object.keys(context.config.api)
|
|
612
|
+
.filter((a) => a !== "authorisation" && a !== "conformance" && a !== "ledger")
|
|
613
|
+
.find((a) => {
|
|
614
|
+
const api = context.config.api[a];
|
|
615
|
+
const contractAddress = context.config.contractAddresses[a];
|
|
616
|
+
return (api.contract &&
|
|
617
|
+
contractId.toLowerCase() === contractAddress.toLowerCase());
|
|
618
|
+
});
|
|
619
|
+
if (!apiName)
|
|
620
|
+
throw new Error(`cannot get API with address ${contractId}`);
|
|
621
|
+
return context.config.api[apiName];
|
|
622
|
+
}
|
|
623
|
+
export function getProperties(input, fragmentInputs) {
|
|
624
|
+
return fragmentInputs.reduce((obj, fragmentInput, index) => {
|
|
625
|
+
const value = Array.isArray(input)
|
|
626
|
+
? input[index]
|
|
627
|
+
: input[fragmentInput.name];
|
|
628
|
+
obj[fragmentInput.name] = toPlainAbiValue(value, fragmentInput);
|
|
629
|
+
return obj;
|
|
630
|
+
}, {});
|
|
631
|
+
}
|
|
632
|
+
export function getUserPin(did) {
|
|
633
|
+
return createHash("sha256")
|
|
634
|
+
.update(did)
|
|
635
|
+
.digest()
|
|
636
|
+
.slice(-4)
|
|
637
|
+
.map((byte) => byte % 10)
|
|
638
|
+
.reduce((acc, digit) => `${acc}${digit}`, "");
|
|
639
|
+
}
|
|
640
|
+
export function sha256(data) {
|
|
641
|
+
let hash = createHash("sha256");
|
|
642
|
+
hash = data.startsWith("0x")
|
|
643
|
+
? hash.update(removePrefix0x(data), "hex")
|
|
644
|
+
: hash.update(data, "utf8");
|
|
645
|
+
return hash.digest().toString("hex");
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Turn ethers ABI-decoded values (including struct/tuple {@link Result} arrays)
|
|
649
|
+
* into plain JSON-serializable objects.
|
|
650
|
+
*/
|
|
651
|
+
export function toPlainAbiValue(value, param) {
|
|
652
|
+
if (value == null) {
|
|
653
|
+
return value;
|
|
654
|
+
}
|
|
655
|
+
if (param.isTuple()) {
|
|
656
|
+
const components = param.components;
|
|
657
|
+
if (!Array.isArray(value)) {
|
|
658
|
+
throw new TypeError("tuple value must be array-like");
|
|
659
|
+
}
|
|
660
|
+
if (value.length !== components.length) {
|
|
661
|
+
throw new TypeError(`tuple length ${String(value.length)} !== ${String(components.length)}`);
|
|
662
|
+
}
|
|
663
|
+
return components.reduce((obj, component, index) => {
|
|
664
|
+
const key = component.name || `_${String(index)}`;
|
|
665
|
+
obj[key] = toPlainAbiValue(value[index], component);
|
|
666
|
+
return obj;
|
|
667
|
+
}, {});
|
|
668
|
+
}
|
|
669
|
+
if (param.isArray()) {
|
|
670
|
+
if (!Array.isArray(value)) {
|
|
671
|
+
throw new TypeError("array value must be an array");
|
|
672
|
+
}
|
|
673
|
+
return value.map((v) => toPlainAbiValue(v, param.arrayChildren));
|
|
674
|
+
}
|
|
675
|
+
if (typeof value === "bigint") {
|
|
676
|
+
return value.toString();
|
|
677
|
+
}
|
|
678
|
+
return value;
|
|
679
|
+
}
|
|
680
|
+
//# sourceMappingURL=compute.js.map
|