@0xpolygonid/js-sdk 1.21.3 → 1.24.1
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/browser/esm/index.js +4378 -545
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/browser/umd/index.js +4388 -545
- package/dist/browser/umd/index.js.map +1 -1
- package/dist/node/cjs/credentials/credential-wallet.js +11 -78
- package/dist/node/cjs/credentials/index.js +1 -0
- package/dist/node/cjs/credentials/status/did-resolver-revocation.js +21 -0
- package/dist/node/cjs/iden3comm/constants.js +25 -1
- package/dist/node/cjs/iden3comm/handlers/auth.js +52 -8
- package/dist/node/cjs/iden3comm/handlers/common.js +13 -1
- package/dist/node/cjs/iden3comm/handlers/contract-request.js +5 -1
- package/dist/node/cjs/iden3comm/handlers/credential-proposal.js +14 -3
- package/dist/node/cjs/iden3comm/handlers/fetch.js +44 -2
- package/dist/node/cjs/iden3comm/handlers/message-handler.js +4 -0
- package/dist/node/cjs/iden3comm/handlers/payment.js +265 -28
- package/dist/node/cjs/iden3comm/handlers/revocation-status.js +4 -0
- package/dist/node/cjs/iden3comm/index.js +1 -0
- package/dist/node/cjs/iden3comm/packageManager.js +12 -0
- package/dist/node/cjs/iden3comm/packers/jws.js +21 -0
- package/dist/node/cjs/iden3comm/packers/plain.js +19 -0
- package/dist/node/cjs/iden3comm/packers/zkp.js +25 -0
- package/dist/node/cjs/iden3comm/types/index.js +1 -0
- package/dist/node/cjs/iden3comm/types/protocol/accept-profile.js +2 -0
- package/dist/node/cjs/iden3comm/utils/accept-profile.js +107 -0
- package/dist/node/cjs/iden3comm/utils/index.js +1 -0
- package/dist/node/cjs/storage/blockchain/abi/ERC20.json +1 -0
- package/dist/node/cjs/storage/blockchain/abi/ERC20Permit.json +1 -0
- package/dist/node/cjs/storage/blockchain/did-resolver-readonly-storage.js +72 -0
- package/dist/node/cjs/storage/blockchain/erc20-helper.js +59 -0
- package/dist/node/cjs/storage/blockchain/index.js +3 -0
- package/dist/node/cjs/storage/blockchain/onchain-issuer-adapter/non-merklized/version/v0.0.1/onchain-non-merklized-issuer-adapter.js +245 -0
- package/dist/node/cjs/storage/blockchain/onchain-issuer.js +82 -0
- package/dist/node/cjs/storage/blockchain/onchain-zkp-verifier.js +38 -34
- package/dist/node/cjs/storage/interfaces/index.js +1 -0
- package/dist/node/cjs/storage/interfaces/onchain-issuer.js +2 -0
- package/dist/node/cjs/utils/did-helper.js +3 -3
- package/dist/node/cjs/verifiable/constants.js +29 -11
- package/dist/node/cjs/verifiable/credential.js +86 -0
- package/dist/node/esm/credentials/credential-wallet.js +12 -79
- package/dist/node/esm/credentials/index.js +1 -0
- package/dist/node/esm/credentials/status/did-resolver-revocation.js +17 -0
- package/dist/node/esm/iden3comm/constants.js +24 -0
- package/dist/node/esm/iden3comm/handlers/auth.js +55 -11
- package/dist/node/esm/iden3comm/handlers/common.js +11 -0
- package/dist/node/esm/iden3comm/handlers/contract-request.js +7 -3
- package/dist/node/esm/iden3comm/handlers/credential-proposal.js +15 -4
- package/dist/node/esm/iden3comm/handlers/fetch.js +44 -2
- package/dist/node/esm/iden3comm/handlers/message-handler.js +4 -0
- package/dist/node/esm/iden3comm/handlers/payment.js +264 -29
- package/dist/node/esm/iden3comm/handlers/revocation-status.js +4 -0
- package/dist/node/esm/iden3comm/index.js +1 -0
- package/dist/node/esm/iden3comm/packageManager.js +12 -0
- package/dist/node/esm/iden3comm/packers/jws.js +22 -1
- package/dist/node/esm/iden3comm/packers/plain.js +19 -0
- package/dist/node/esm/iden3comm/packers/zkp.js +26 -1
- package/dist/node/esm/iden3comm/types/index.js +1 -0
- package/dist/node/esm/iden3comm/types/protocol/accept-profile.js +1 -0
- package/dist/node/esm/iden3comm/utils/accept-profile.js +102 -0
- package/dist/node/esm/iden3comm/utils/index.js +1 -0
- package/dist/node/esm/storage/blockchain/abi/ERC20.json +1 -0
- package/dist/node/esm/storage/blockchain/abi/ERC20Permit.json +1 -0
- package/dist/node/esm/storage/blockchain/did-resolver-readonly-storage.js +68 -0
- package/dist/node/esm/storage/blockchain/erc20-helper.js +51 -0
- package/dist/node/esm/storage/blockchain/index.js +3 -0
- package/dist/node/esm/storage/blockchain/onchain-issuer-adapter/non-merklized/version/v0.0.1/onchain-non-merklized-issuer-adapter.js +241 -0
- package/dist/node/esm/storage/blockchain/onchain-issuer.js +78 -0
- package/dist/node/esm/storage/blockchain/onchain-zkp-verifier.js +38 -34
- package/dist/node/esm/storage/interfaces/index.js +1 -0
- package/dist/node/esm/storage/interfaces/onchain-issuer.js +1 -0
- package/dist/node/esm/utils/did-helper.js +3 -3
- package/dist/node/esm/verifiable/constants.js +28 -10
- package/dist/node/esm/verifiable/credential.js +88 -2
- package/dist/types/credentials/credential-wallet.d.ts +0 -6
- package/dist/types/credentials/index.d.ts +1 -0
- package/dist/types/credentials/models.d.ts +8 -0
- package/dist/types/credentials/status/did-resolver-revocation.d.ts +7 -0
- package/dist/types/iden3comm/constants.d.ts +16 -0
- package/dist/types/iden3comm/handlers/auth.d.ts +19 -7
- package/dist/types/iden3comm/handlers/common.d.ts +7 -1
- package/dist/types/iden3comm/handlers/contract-request.d.ts +2 -2
- package/dist/types/iden3comm/handlers/credential-proposal.d.ts +9 -4
- package/dist/types/iden3comm/handlers/fetch.d.ts +30 -6
- package/dist/types/iden3comm/handlers/message-handler.d.ts +6 -0
- package/dist/types/iden3comm/handlers/payment.d.ts +71 -10
- package/dist/types/iden3comm/handlers/revocation-status.d.ts +2 -2
- package/dist/types/iden3comm/index.d.ts +1 -0
- package/dist/types/iden3comm/packageManager.d.ts +4 -0
- package/dist/types/iden3comm/packers/jws.d.ts +5 -0
- package/dist/types/iden3comm/packers/plain.d.ts +4 -0
- package/dist/types/iden3comm/packers/zkp.d.ts +6 -0
- package/dist/types/iden3comm/types/index.d.ts +1 -0
- package/dist/types/iden3comm/types/packageManager.d.ts +14 -0
- package/dist/types/iden3comm/types/packer.d.ts +25 -0
- package/dist/types/iden3comm/types/protocol/accept-profile.d.ts +7 -0
- package/dist/types/iden3comm/types/protocol/auth.d.ts +1 -0
- package/dist/types/iden3comm/types/protocol/credentials.d.ts +6 -6
- package/dist/types/iden3comm/types/protocol/messages.d.ts +2 -2
- package/dist/types/iden3comm/types/protocol/payment.d.ts +87 -13
- package/dist/types/iden3comm/types/protocol/proof.d.ts +3 -3
- package/dist/types/iden3comm/types/protocol/revocation.d.ts +2 -2
- package/dist/types/iden3comm/utils/accept-profile.d.ts +3 -0
- package/dist/types/iden3comm/utils/index.d.ts +1 -0
- package/dist/types/storage/blockchain/did-resolver-readonly-storage.d.ts +16 -0
- package/dist/types/storage/blockchain/erc20-helper.d.ts +19 -0
- package/dist/types/storage/blockchain/index.d.ts +3 -0
- package/dist/types/storage/blockchain/onchain-issuer-adapter/non-merklized/version/v0.0.1/onchain-non-merklized-issuer-adapter.d.ts +66 -0
- package/dist/types/storage/blockchain/onchain-issuer.d.ts +40 -0
- package/dist/types/storage/blockchain/onchain-zkp-verifier.d.ts +11 -12
- package/dist/types/storage/entities/state.d.ts +2 -0
- package/dist/types/storage/interfaces/index.d.ts +1 -0
- package/dist/types/storage/interfaces/onchain-issuer.d.ts +12 -0
- package/dist/types/verifiable/constants.d.ts +28 -11
- package/dist/types/verifiable/credential.d.ts +15 -2
- package/package.json +3 -2
|
@@ -23,3 +23,4 @@ __exportStar(require("./data-source"), exports);
|
|
|
23
23
|
__exportStar(require("./circuits"), exports);
|
|
24
24
|
__exportStar(require("./onchain-zkp-verifier"), exports);
|
|
25
25
|
__exportStar(require("./onchain-revocation"), exports);
|
|
26
|
+
__exportStar(require("./onchain-issuer"), exports);
|
|
@@ -72,7 +72,7 @@ const validateDIDDocumentAuth = async (did, resolverURL, state) => {
|
|
|
72
72
|
};
|
|
73
73
|
exports.validateDIDDocumentAuth = validateDIDDocumentAuth;
|
|
74
74
|
const resolveDIDDocumentAuth = async (did, resolveURL, state) => {
|
|
75
|
-
let url = `${resolveURL}/${did.string()
|
|
75
|
+
let url = `${resolveURL}/${encodeURIComponent(did.string())}`;
|
|
76
76
|
if (state) {
|
|
77
77
|
url += `?state=${state.hex()}`;
|
|
78
78
|
}
|
|
@@ -89,11 +89,11 @@ function emptyStateDID(did) {
|
|
|
89
89
|
return emptyDID;
|
|
90
90
|
}
|
|
91
91
|
const resolveDidDocument = async (did, resolverUrl, opts) => {
|
|
92
|
-
let didString = did.string()
|
|
92
|
+
let didString = encodeURIComponent(did.string());
|
|
93
93
|
// for gist resolve we have to `hide` user did (look into resolver implementation)
|
|
94
94
|
const isGistRequest = opts?.gist && !opts.state;
|
|
95
95
|
if (isGistRequest) {
|
|
96
|
-
didString = emptyStateDID(did).string();
|
|
96
|
+
didString = encodeURIComponent(emptyStateDID(did).string());
|
|
97
97
|
}
|
|
98
98
|
let url = `${resolverUrl}/1.0/identifiers/${didString}`;
|
|
99
99
|
if (opts?.signature) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DisplayMethodType = exports.SupportedCurrencies = exports.
|
|
3
|
+
exports.DisplayMethodType = exports.PaymentFeatures = exports.SupportedCurrencies = exports.SupportedPaymentProofType = exports.PaymentType = exports.PaymentRequestDataType = exports.RefreshServiceType = exports.SubjectPosition = exports.MerklizedRootPosition = exports.ProofPurpose = exports.CredentialStatusType = exports.ProofType = exports.VerifiableConstants = void 0;
|
|
4
4
|
/** Verifiable constants */
|
|
5
5
|
exports.VerifiableConstants = Object.freeze({
|
|
6
6
|
ERRORS: {
|
|
@@ -115,15 +115,6 @@ var RefreshServiceType;
|
|
|
115
115
|
(function (RefreshServiceType) {
|
|
116
116
|
RefreshServiceType["Iden3RefreshService2023"] = "Iden3RefreshService2023";
|
|
117
117
|
})(RefreshServiceType = exports.RefreshServiceType || (exports.RefreshServiceType = {}));
|
|
118
|
-
/**
|
|
119
|
-
* PaymentRequestType type for payment requests
|
|
120
|
-
* @beta
|
|
121
|
-
* @enum {string}
|
|
122
|
-
*/
|
|
123
|
-
var PaymentRequestType;
|
|
124
|
-
(function (PaymentRequestType) {
|
|
125
|
-
PaymentRequestType["PaymentRequest"] = "PaymentRequest";
|
|
126
|
-
})(PaymentRequestType = exports.PaymentRequestType || (exports.PaymentRequestType = {}));
|
|
127
118
|
/**
|
|
128
119
|
* PaymentRequestDataType type for payment requests
|
|
129
120
|
* @beta
|
|
@@ -132,6 +123,8 @@ var PaymentRequestType;
|
|
|
132
123
|
var PaymentRequestDataType;
|
|
133
124
|
(function (PaymentRequestDataType) {
|
|
134
125
|
PaymentRequestDataType["Iden3PaymentRequestCryptoV1"] = "Iden3PaymentRequestCryptoV1";
|
|
126
|
+
PaymentRequestDataType["Iden3PaymentRailsRequestV1"] = "Iden3PaymentRailsRequestV1";
|
|
127
|
+
PaymentRequestDataType["Iden3PaymentRailsERC20RequestV1"] = "Iden3PaymentRailsERC20RequestV1";
|
|
135
128
|
})(PaymentRequestDataType = exports.PaymentRequestDataType || (exports.PaymentRequestDataType = {}));
|
|
136
129
|
/**
|
|
137
130
|
* PaymentType type for payment responses
|
|
@@ -141,17 +134,42 @@ var PaymentRequestDataType;
|
|
|
141
134
|
var PaymentType;
|
|
142
135
|
(function (PaymentType) {
|
|
143
136
|
PaymentType["Iden3PaymentCryptoV1"] = "Iden3PaymentCryptoV1";
|
|
137
|
+
PaymentType["Iden3PaymentRailsV1"] = "Iden3PaymentRailsV1";
|
|
138
|
+
PaymentType["Iden3PaymentRailsERC20V1"] = "Iden3PaymentRailsERC20V1";
|
|
144
139
|
})(PaymentType = exports.PaymentType || (exports.PaymentType = {}));
|
|
140
|
+
/**
|
|
141
|
+
* SupportedPaymentProofType type for payment proofs
|
|
142
|
+
* @beta
|
|
143
|
+
* @enum {string}
|
|
144
|
+
*/
|
|
145
|
+
var SupportedPaymentProofType;
|
|
146
|
+
(function (SupportedPaymentProofType) {
|
|
147
|
+
SupportedPaymentProofType["EthereumEip712Signature2021"] = "EthereumEip712Signature2021";
|
|
148
|
+
})(SupportedPaymentProofType = exports.SupportedPaymentProofType || (exports.SupportedPaymentProofType = {}));
|
|
145
149
|
/**
|
|
146
150
|
* Media types for Payment supported currencies
|
|
147
151
|
* @beta
|
|
148
|
-
* @enum {
|
|
152
|
+
* @enum {string}
|
|
149
153
|
*/
|
|
150
154
|
var SupportedCurrencies;
|
|
151
155
|
(function (SupportedCurrencies) {
|
|
152
156
|
SupportedCurrencies["ETH"] = "ETH";
|
|
157
|
+
SupportedCurrencies["ETH_WEI"] = "ETHWEI";
|
|
158
|
+
SupportedCurrencies["ETH_GWEI"] = "ETHGWEI";
|
|
153
159
|
SupportedCurrencies["MATIC"] = "MATIC";
|
|
160
|
+
SupportedCurrencies["POL"] = "POL";
|
|
161
|
+
SupportedCurrencies["USDT"] = "USDT";
|
|
162
|
+
SupportedCurrencies["USDC"] = "USDC";
|
|
154
163
|
})(SupportedCurrencies = exports.SupportedCurrencies || (exports.SupportedCurrencies = {}));
|
|
164
|
+
/**
|
|
165
|
+
* Supported features for payment-request
|
|
166
|
+
* @beta
|
|
167
|
+
* @enum {string}
|
|
168
|
+
*/
|
|
169
|
+
var PaymentFeatures;
|
|
170
|
+
(function (PaymentFeatures) {
|
|
171
|
+
PaymentFeatures["EIP_2612"] = "EIP-2612";
|
|
172
|
+
})(PaymentFeatures = exports.PaymentFeatures || (exports.PaymentFeatures = {}));
|
|
155
173
|
/**
|
|
156
174
|
* DisplayMethodType type for display method
|
|
157
175
|
*
|
|
@@ -51,6 +51,92 @@ class W3CCredential {
|
|
|
51
51
|
this.credentialSubject = {};
|
|
52
52
|
this.issuer = '';
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param issuer - DID of the issuer
|
|
57
|
+
* @param request - Credential request
|
|
58
|
+
* @returns - W3C Credential
|
|
59
|
+
*/
|
|
60
|
+
static fromCredentialRequest(issuer, request) {
|
|
61
|
+
if (!request.id) {
|
|
62
|
+
throw new Error('Credential id is required');
|
|
63
|
+
}
|
|
64
|
+
if (!request.context) {
|
|
65
|
+
throw new Error('Credential context is required');
|
|
66
|
+
}
|
|
67
|
+
const context = [
|
|
68
|
+
constants_1.VerifiableConstants.JSONLD_SCHEMA.W3C_CREDENTIAL_2018,
|
|
69
|
+
constants_1.VerifiableConstants.JSONLD_SCHEMA.IDEN3_CREDENTIAL,
|
|
70
|
+
...request.context
|
|
71
|
+
];
|
|
72
|
+
const credentialType = [
|
|
73
|
+
constants_1.VerifiableConstants.CREDENTIAL_TYPE.W3C_VERIFIABLE_CREDENTIAL,
|
|
74
|
+
request.type
|
|
75
|
+
];
|
|
76
|
+
const credentialSubject = request.credentialSubject;
|
|
77
|
+
credentialSubject['type'] = request.type;
|
|
78
|
+
const cr = new W3CCredential();
|
|
79
|
+
cr.id = request.id;
|
|
80
|
+
cr['@context'] = context;
|
|
81
|
+
cr.type = credentialType;
|
|
82
|
+
cr.credentialSubject = credentialSubject;
|
|
83
|
+
cr.issuer = issuer.string();
|
|
84
|
+
cr.credentialSchema = {
|
|
85
|
+
id: request.credentialSchema,
|
|
86
|
+
type: constants_1.VerifiableConstants.JSON_SCHEMA_VALIDATOR
|
|
87
|
+
};
|
|
88
|
+
cr.credentialStatus = W3CCredential.buildCredentialStatus(request, issuer);
|
|
89
|
+
request.expiration && (cr.expirationDate = new Date(request.expiration).toISOString());
|
|
90
|
+
request.refreshService && (cr.refreshService = request.refreshService);
|
|
91
|
+
request.displayMethod && (cr.displayMethod = request.displayMethod);
|
|
92
|
+
request.issuanceDate && (cr.issuanceDate = new Date(request.issuanceDate).toISOString());
|
|
93
|
+
return cr;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Builds credential status
|
|
97
|
+
* @param {CredentialRequest} request
|
|
98
|
+
* @returns `CredentialStatus`
|
|
99
|
+
*/
|
|
100
|
+
static buildCredentialStatus(request, issuer) {
|
|
101
|
+
const credentialStatus = {
|
|
102
|
+
id: request.revocationOpts.id,
|
|
103
|
+
type: request.revocationOpts.type,
|
|
104
|
+
revocationNonce: request.revocationOpts.nonce
|
|
105
|
+
};
|
|
106
|
+
switch (request.revocationOpts.type) {
|
|
107
|
+
case constants_1.CredentialStatusType.SparseMerkleTreeProof:
|
|
108
|
+
return {
|
|
109
|
+
...credentialStatus,
|
|
110
|
+
id: `${credentialStatus.id.replace(/\/$/, '')}/${credentialStatus.revocationNonce}`
|
|
111
|
+
};
|
|
112
|
+
case constants_1.CredentialStatusType.Iden3ReverseSparseMerkleTreeProof:
|
|
113
|
+
return {
|
|
114
|
+
...credentialStatus,
|
|
115
|
+
id: request.revocationOpts.issuerState
|
|
116
|
+
? `${credentialStatus.id.replace(/\/$/, '')}/node?state=${request.revocationOpts.issuerState}`
|
|
117
|
+
: `${credentialStatus.id.replace(/\/$/, '')}`
|
|
118
|
+
};
|
|
119
|
+
case constants_1.CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023: {
|
|
120
|
+
const issuerId = js_iden3_core_1.DID.idFromDID(issuer);
|
|
121
|
+
const chainId = (0, js_iden3_core_1.getChainId)(js_iden3_core_1.DID.blockchainFromId(issuerId), js_iden3_core_1.DID.networkIdFromId(issuerId));
|
|
122
|
+
const searchParams = [
|
|
123
|
+
['revocationNonce', request.revocationOpts.nonce?.toString() || ''],
|
|
124
|
+
['contractAddress', `${chainId}:${request.revocationOpts.id}`],
|
|
125
|
+
['state', request.revocationOpts.issuerState || '']
|
|
126
|
+
]
|
|
127
|
+
.filter(([, value]) => Boolean(value))
|
|
128
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
129
|
+
.join('&');
|
|
130
|
+
return {
|
|
131
|
+
...credentialStatus,
|
|
132
|
+
// `[did]:[methodid]:[chain]:[network]:[id]/credentialStatus?(revocationNonce=value)&[contractAddress=[chainID]:[contractAddress]]&(state=issuerState)`
|
|
133
|
+
id: `${issuer.string()}/credentialStatus?${searchParams}`
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
default:
|
|
137
|
+
return credentialStatus;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
54
140
|
toJSON() {
|
|
55
141
|
return {
|
|
56
142
|
...this,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DID
|
|
1
|
+
import { DID } from '@iden3/js-iden3-core';
|
|
2
2
|
import { W3CCredential, VerifiableConstants, CredentialStatusType, DisplayMethodType } from './../verifiable';
|
|
3
3
|
import * as uuid from 'uuid';
|
|
4
4
|
import { CredentialStatusResolverRegistry } from './status/resolver';
|
|
@@ -31,40 +31,18 @@ export class CredentialWallet {
|
|
|
31
31
|
if (!schema.$metadata.uris['jsonLdContext']) {
|
|
32
32
|
throw new Error('jsonLdContext is missing is the schema');
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
// do copy of request to avoid mutation
|
|
35
|
+
const r = { ...request };
|
|
36
|
+
r.context = r.context ?? [];
|
|
37
|
+
if (r.displayMethod?.type === DisplayMethodType.Iden3BasicDisplayMethodV1 &&
|
|
38
|
+
!r.context.includes(VerifiableConstants.JSONLD_SCHEMA.IDEN3_DISPLAY_METHOD)) {
|
|
39
|
+
r.context.push(VerifiableConstants.JSONLD_SCHEMA.IDEN3_DISPLAY_METHOD);
|
|
38
40
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
];
|
|
45
|
-
const credentialType = [
|
|
46
|
-
VerifiableConstants.CREDENTIAL_TYPE.W3C_VERIFIABLE_CREDENTIAL,
|
|
47
|
-
request.type
|
|
48
|
-
];
|
|
49
|
-
const expirationDate = !request.expiration || request.expiration == 0 ? null : request.expiration;
|
|
50
|
-
const credentialSubject = request.credentialSubject;
|
|
51
|
-
credentialSubject['type'] = request.type;
|
|
52
|
-
const cr = new W3CCredential();
|
|
53
|
-
cr.id = `urn:${uuid.v4()}`;
|
|
54
|
-
cr['@context'] = context;
|
|
55
|
-
cr.type = credentialType;
|
|
56
|
-
cr.expirationDate = expirationDate ? new Date(expirationDate * 1000).toISOString() : undefined;
|
|
57
|
-
cr.refreshService = request.refreshService;
|
|
58
|
-
cr.displayMethod = request.displayMethod;
|
|
59
|
-
cr.issuanceDate = new Date().toISOString();
|
|
60
|
-
cr.credentialSubject = credentialSubject;
|
|
61
|
-
cr.issuer = issuer.string();
|
|
62
|
-
cr.credentialSchema = {
|
|
63
|
-
id: request.credentialSchema,
|
|
64
|
-
type: VerifiableConstants.JSON_SCHEMA_VALIDATOR
|
|
65
|
-
};
|
|
66
|
-
cr.credentialStatus = this.buildCredentialStatus(request, issuer);
|
|
67
|
-
return cr;
|
|
41
|
+
r.context.push(schema.$metadata.uris['jsonLdContext']);
|
|
42
|
+
r.expiration = r.expiration ? r.expiration * 1000 : undefined;
|
|
43
|
+
r.id = r.id ? r.id : `urn:${uuid.v4()}`;
|
|
44
|
+
r.issuanceDate = r.issuanceDate ? r.issuanceDate * 1000 : Date.now();
|
|
45
|
+
return W3CCredential.fromCredentialRequest(issuer, r);
|
|
68
46
|
};
|
|
69
47
|
// if no credential status resolvers are provided
|
|
70
48
|
// register default issuer resolver
|
|
@@ -134,51 +112,6 @@ export class CredentialWallet {
|
|
|
134
112
|
}
|
|
135
113
|
return statusResolver.resolve(credStatus, credentialStatusResolveOptions);
|
|
136
114
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Builds credential status
|
|
139
|
-
* @param {CredentialRequest} request
|
|
140
|
-
* @returns `CredentialStatus`
|
|
141
|
-
*/
|
|
142
|
-
buildCredentialStatus(request, issuer) {
|
|
143
|
-
const credentialStatus = {
|
|
144
|
-
id: request.revocationOpts.id,
|
|
145
|
-
type: request.revocationOpts.type,
|
|
146
|
-
revocationNonce: request.revocationOpts.nonce
|
|
147
|
-
};
|
|
148
|
-
switch (request.revocationOpts.type) {
|
|
149
|
-
case CredentialStatusType.SparseMerkleTreeProof:
|
|
150
|
-
return {
|
|
151
|
-
...credentialStatus,
|
|
152
|
-
id: `${credentialStatus.id.replace(/\/$/, '')}/${credentialStatus.revocationNonce}`
|
|
153
|
-
};
|
|
154
|
-
case CredentialStatusType.Iden3ReverseSparseMerkleTreeProof:
|
|
155
|
-
return {
|
|
156
|
-
...credentialStatus,
|
|
157
|
-
id: request.revocationOpts.issuerState
|
|
158
|
-
? `${credentialStatus.id.replace(/\/$/, '')}/node?state=${request.revocationOpts.issuerState}`
|
|
159
|
-
: `${credentialStatus.id.replace(/\/$/, '')}`
|
|
160
|
-
};
|
|
161
|
-
case CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023: {
|
|
162
|
-
const issuerId = DID.idFromDID(issuer);
|
|
163
|
-
const chainId = getChainId(DID.blockchainFromId(issuerId), DID.networkIdFromId(issuerId));
|
|
164
|
-
const searchParams = [
|
|
165
|
-
['revocationNonce', request.revocationOpts.nonce?.toString() || ''],
|
|
166
|
-
['contractAddress', `${chainId}:${request.revocationOpts.id}`],
|
|
167
|
-
['state', request.revocationOpts.issuerState || '']
|
|
168
|
-
]
|
|
169
|
-
.filter(([, value]) => Boolean(value))
|
|
170
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
171
|
-
.join('&');
|
|
172
|
-
return {
|
|
173
|
-
...credentialStatus,
|
|
174
|
-
// `[did]:[methodid]:[chain]:[network]:[id]/credentialStatus?(revocationNonce=value)&[contractAddress=[chainID]:[contractAddress]]&(state=issuerState)`
|
|
175
|
-
id: `${issuer.string()}/credentialStatus?${searchParams}`
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
default:
|
|
179
|
-
return credentialStatus;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
115
|
/**
|
|
183
116
|
* {@inheritDoc ICredentialWallet.findById}
|
|
184
117
|
*/
|
|
@@ -4,6 +4,7 @@ export * from './status/sparse-merkle-tree';
|
|
|
4
4
|
export * from './status/resolver';
|
|
5
5
|
export * from './status/agent-revocation';
|
|
6
6
|
export * from './status/credential-status-publisher';
|
|
7
|
+
export * from './status/did-resolver-revocation';
|
|
7
8
|
export * from './credential-wallet';
|
|
8
9
|
export * from './rhs';
|
|
9
10
|
export * from './utils';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class DidDocumentCredentialStatusResolver {
|
|
2
|
+
constructor(didResolverUrl) {
|
|
3
|
+
this.didResolverUrl = didResolverUrl;
|
|
4
|
+
}
|
|
5
|
+
async resolve(credentialStatus, opts) {
|
|
6
|
+
if (!opts?.issuerDID) {
|
|
7
|
+
throw new Error('IssuerDID is not set in options');
|
|
8
|
+
}
|
|
9
|
+
const url = `${this.didResolverUrl}/1.0/credential-status/${encodeURIComponent(opts.issuerDID.string())}`;
|
|
10
|
+
const resp = await fetch(url, {
|
|
11
|
+
method: 'POST',
|
|
12
|
+
body: JSON.stringify(credentialStatus)
|
|
13
|
+
});
|
|
14
|
+
const data = await resp.json();
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -73,5 +73,29 @@ export const SUPPORTED_PUBLIC_KEY_TYPES = {
|
|
|
73
73
|
'JsonWebKey2020'
|
|
74
74
|
]
|
|
75
75
|
};
|
|
76
|
+
export var ProtocolVersion;
|
|
77
|
+
(function (ProtocolVersion) {
|
|
78
|
+
ProtocolVersion["V1"] = "iden3comm/v1";
|
|
79
|
+
})(ProtocolVersion || (ProtocolVersion = {}));
|
|
80
|
+
export var AcceptAuthCircuits;
|
|
81
|
+
(function (AcceptAuthCircuits) {
|
|
82
|
+
AcceptAuthCircuits["AuthV2"] = "authV2";
|
|
83
|
+
AcceptAuthCircuits["AuthV3"] = "authV3";
|
|
84
|
+
})(AcceptAuthCircuits || (AcceptAuthCircuits = {}));
|
|
85
|
+
export var AcceptJwzAlgorithms;
|
|
86
|
+
(function (AcceptJwzAlgorithms) {
|
|
87
|
+
AcceptJwzAlgorithms["Groth16"] = "groth16";
|
|
88
|
+
})(AcceptJwzAlgorithms || (AcceptJwzAlgorithms = {}));
|
|
89
|
+
export var AcceptJwsAlgorithms;
|
|
90
|
+
(function (AcceptJwsAlgorithms) {
|
|
91
|
+
AcceptJwsAlgorithms["ES256K"] = "ES256K";
|
|
92
|
+
AcceptJwsAlgorithms["ES256KR"] = "ES256K-R";
|
|
93
|
+
})(AcceptJwsAlgorithms || (AcceptJwsAlgorithms = {}));
|
|
94
|
+
export const defaultAcceptProfile = {
|
|
95
|
+
protocolVersion: ProtocolVersion.V1,
|
|
96
|
+
env: MediaType.ZKPMessage,
|
|
97
|
+
circuits: [AcceptAuthCircuits.AuthV2],
|
|
98
|
+
alg: [AcceptJwzAlgorithms.Groth16]
|
|
99
|
+
};
|
|
76
100
|
export const DEFAULT_PROOF_VERIFY_DELAY = 1 * 60 * 60 * 1000; // 1 hour
|
|
77
101
|
export const DEFAULT_AUTH_VERIFY_DELAY = 5 * 60 * 1000; // 5 minutes
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { MediaType } from '../constants';
|
|
1
|
+
import { MediaType, ProtocolVersion } from '../constants';
|
|
2
2
|
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
|
|
3
|
-
import { DID } from '@iden3/js-iden3-core';
|
|
3
|
+
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
|
|
4
4
|
import { proving } from '@iden3/js-jwz';
|
|
5
5
|
import * as uuid from 'uuid';
|
|
6
6
|
import { byteDecoder, byteEncoder } from '../../utils';
|
|
7
|
-
import { processZeroKnowledgeProofRequests } from './common';
|
|
7
|
+
import { processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
|
|
8
8
|
import { CircuitId } from '../../circuits';
|
|
9
9
|
import { AbstractMessageHandler } from './message-handler';
|
|
10
|
+
import { parseAcceptProfile } from '../utils';
|
|
10
11
|
/**
|
|
11
12
|
* createAuthorizationRequest is a function to create protocol authorization request
|
|
12
13
|
* @param {string} reason - reason to request proof
|
|
13
14
|
* @param {string} sender - sender did
|
|
14
15
|
* @param {string} callbackUrl - callback that user should use to send response
|
|
16
|
+
* @param {AuthorizationRequestCreateOptions} opts - authorization request options
|
|
15
17
|
* @returns `Promise<AuthorizationRequestMessage>`
|
|
16
18
|
*/
|
|
17
|
-
export function createAuthorizationRequest(reason, sender, callbackUrl) {
|
|
18
|
-
return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl);
|
|
19
|
+
export function createAuthorizationRequest(reason, sender, callbackUrl, opts) {
|
|
20
|
+
return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl, opts);
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* createAuthorizationRequestWithMessage is a function to create protocol authorization request with explicit message to sign
|
|
@@ -23,9 +25,10 @@ export function createAuthorizationRequest(reason, sender, callbackUrl) {
|
|
|
23
25
|
* @param {string} message - message to sign in the response
|
|
24
26
|
* @param {string} sender - sender did
|
|
25
27
|
* @param {string} callbackUrl - callback that user should use to send response
|
|
28
|
+
* @param {AuthorizationRequestCreateOptions} opts - authorization request options
|
|
26
29
|
* @returns `Promise<AuthorizationRequestMessage>`
|
|
27
30
|
*/
|
|
28
|
-
export function createAuthorizationRequestWithMessage(reason, message, sender, callbackUrl) {
|
|
31
|
+
export function createAuthorizationRequestWithMessage(reason, message, sender, callbackUrl, opts) {
|
|
29
32
|
const uuidv4 = uuid.v4();
|
|
30
33
|
const request = {
|
|
31
34
|
id: uuidv4,
|
|
@@ -34,11 +37,14 @@ export function createAuthorizationRequestWithMessage(reason, message, sender, c
|
|
|
34
37
|
typ: MediaType.PlainMessage,
|
|
35
38
|
type: PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_REQUEST_MESSAGE_TYPE,
|
|
36
39
|
body: {
|
|
40
|
+
accept: opts?.accept,
|
|
37
41
|
reason: reason,
|
|
38
42
|
message: message,
|
|
39
43
|
callbackUrl: callbackUrl,
|
|
40
|
-
scope: []
|
|
41
|
-
}
|
|
44
|
+
scope: opts?.scope ?? []
|
|
45
|
+
},
|
|
46
|
+
created_time: getUnixTimestamp(new Date()),
|
|
47
|
+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
|
|
42
48
|
};
|
|
43
49
|
return request;
|
|
44
50
|
}
|
|
@@ -97,17 +103,18 @@ export class AuthHandler extends AbstractMessageHandler {
|
|
|
97
103
|
}
|
|
98
104
|
// override sender did if it's explicitly specified in the auth request
|
|
99
105
|
const to = authRequest.to ? DID.parse(authRequest.to) : ctx.senderDid;
|
|
100
|
-
const mediaType = ctx.mediaType || MediaType.ZKPMessage;
|
|
101
106
|
const guid = uuid.v4();
|
|
102
107
|
if (!authRequest.from) {
|
|
103
108
|
throw new Error('auth request should contain from field');
|
|
104
109
|
}
|
|
110
|
+
const responseType = PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_RESPONSE_MESSAGE_TYPE;
|
|
111
|
+
const mediaType = this.getSupportedMediaTypeByProfile(ctx, responseType, authRequest.body.accept);
|
|
105
112
|
const from = DID.parse(authRequest.from);
|
|
106
113
|
const responseScope = await processZeroKnowledgeProofRequests(to, authRequest?.body.scope, from, this._proofService, { mediaType, supportedCircuits: this._supportedCircuits });
|
|
107
114
|
return {
|
|
108
115
|
id: guid,
|
|
109
|
-
typ:
|
|
110
|
-
type:
|
|
116
|
+
typ: mediaType,
|
|
117
|
+
type: responseType,
|
|
111
118
|
thid: authRequest.thid ?? guid,
|
|
112
119
|
body: {
|
|
113
120
|
message: authRequest?.body?.message,
|
|
@@ -122,6 +129,9 @@ export class AuthHandler extends AbstractMessageHandler {
|
|
|
122
129
|
*/
|
|
123
130
|
async handleAuthorizationRequest(did, request, opts) {
|
|
124
131
|
const authRequest = await this.parseAuthorizationRequest(request);
|
|
132
|
+
if (!opts?.allowExpiredMessages) {
|
|
133
|
+
verifyExpiresTime(authRequest);
|
|
134
|
+
}
|
|
125
135
|
if (!opts) {
|
|
126
136
|
opts = {
|
|
127
137
|
mediaType: MediaType.ZKPMessage
|
|
@@ -211,6 +221,9 @@ export class AuthHandler extends AbstractMessageHandler {
|
|
|
211
221
|
* @inheritdoc IAuthHandler#handleAuthorizationResponse
|
|
212
222
|
*/
|
|
213
223
|
async handleAuthorizationResponse(response, request, opts) {
|
|
224
|
+
if (!opts?.allowExpiredMessages) {
|
|
225
|
+
verifyExpiresTime(response);
|
|
226
|
+
}
|
|
214
227
|
const authResp = (await this.handleAuthResponse(response, {
|
|
215
228
|
request,
|
|
216
229
|
acceptedStateTransitionDelay: opts?.acceptedStateTransitionDelay,
|
|
@@ -244,4 +257,35 @@ export class AuthHandler extends AbstractMessageHandler {
|
|
|
244
257
|
}
|
|
245
258
|
}
|
|
246
259
|
}
|
|
260
|
+
getSupportedMediaTypeByProfile(ctx, responseType, profile) {
|
|
261
|
+
let mediaType;
|
|
262
|
+
if (profile?.length) {
|
|
263
|
+
const supportedMediaTypes = [];
|
|
264
|
+
for (const acceptProfile of profile) {
|
|
265
|
+
// 1. check protocol version
|
|
266
|
+
const { protocolVersion, env } = parseAcceptProfile(acceptProfile);
|
|
267
|
+
const responseTypeVersion = Number(responseType.split('/').at(-2));
|
|
268
|
+
if (protocolVersion !== ProtocolVersion.V1 ||
|
|
269
|
+
(protocolVersion === ProtocolVersion.V1 &&
|
|
270
|
+
(responseTypeVersion < 1 || responseTypeVersion >= 2))) {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
// 2. check packer support
|
|
274
|
+
if (this._packerMgr.isProfileSupported(env, acceptProfile)) {
|
|
275
|
+
supportedMediaTypes.push(env);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!supportedMediaTypes.length) {
|
|
279
|
+
throw new Error('no packer with profile which meets `accept` header requirements');
|
|
280
|
+
}
|
|
281
|
+
mediaType = supportedMediaTypes[0];
|
|
282
|
+
if (ctx.mediaType && supportedMediaTypes.includes(ctx.mediaType)) {
|
|
283
|
+
mediaType = ctx.mediaType;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
mediaType = ctx.mediaType || MediaType.ZKPMessage;
|
|
288
|
+
}
|
|
289
|
+
return mediaType;
|
|
290
|
+
}
|
|
247
291
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getRandomBytes } from '@iden3/js-crypto';
|
|
2
2
|
import { mergeObjects } from '../../utils';
|
|
3
|
+
import { getUnixTimestamp } from '@iden3/js-iden3-core';
|
|
3
4
|
/**
|
|
4
5
|
* Groups the ZeroKnowledgeProofRequest objects based on their groupId.
|
|
5
6
|
* Returns a Map where the key is the groupId and the value is an object containing the query and linkNonce.
|
|
@@ -79,3 +80,13 @@ export const processZeroKnowledgeProofRequests = async (to, requests, from, proo
|
|
|
79
80
|
}
|
|
80
81
|
return zkpResponses;
|
|
81
82
|
};
|
|
83
|
+
/**
|
|
84
|
+
* Verifies that the expires_time field of a message is not in the past. Throws an error if it is.
|
|
85
|
+
*
|
|
86
|
+
* @param message - Basic message to verify.
|
|
87
|
+
*/
|
|
88
|
+
export const verifyExpiresTime = (message) => {
|
|
89
|
+
if (message?.expires_time && message.expires_time < getUnixTimestamp(new Date())) {
|
|
90
|
+
throw new Error('Message expired');
|
|
91
|
+
}
|
|
92
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CircuitId } from '../../circuits/models';
|
|
2
2
|
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
|
|
3
|
-
import { DID, ChainIds } from '@iden3/js-iden3-core';
|
|
3
|
+
import { DID, ChainIds, getUnixTimestamp } from '@iden3/js-iden3-core';
|
|
4
4
|
import { FunctionSignatures } from '../../storage';
|
|
5
|
-
import { processZeroKnowledgeProofRequests } from './common';
|
|
5
|
+
import { processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
|
|
6
6
|
import { AbstractMessageHandler } from './message-handler';
|
|
7
7
|
/**
|
|
8
8
|
*
|
|
@@ -107,7 +107,8 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
107
107
|
body: {
|
|
108
108
|
transaction_data: request.body.transaction_data,
|
|
109
109
|
scope: []
|
|
110
|
-
}
|
|
110
|
+
},
|
|
111
|
+
created_time: getUnixTimestamp(new Date())
|
|
111
112
|
};
|
|
112
113
|
for (const [txHash, zkpResponses] of txHashToZkpResponseMap) {
|
|
113
114
|
for (const zkpResponse of zkpResponses) {
|
|
@@ -131,6 +132,9 @@ export class ContractRequestHandler extends AbstractMessageHandler {
|
|
|
131
132
|
*/
|
|
132
133
|
async handleContractInvokeRequest(did, request, opts) {
|
|
133
134
|
const ciRequest = await this.parseContractInvokeRequest(request);
|
|
135
|
+
if (!opts.allowExpiredMessages) {
|
|
136
|
+
verifyExpiresTime(ciRequest);
|
|
137
|
+
}
|
|
134
138
|
if (ciRequest.body.transaction_data.method_id !== FunctionSignatures.SubmitZKPResponseV1) {
|
|
135
139
|
throw new Error(`please use handle method to work with other method ids`);
|
|
136
140
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { PROTOCOL_MESSAGE_TYPE, MediaType } from '../constants';
|
|
2
|
-
import { DID } from '@iden3/js-iden3-core';
|
|
2
|
+
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
|
|
3
3
|
import * as uuid from 'uuid';
|
|
4
4
|
import { proving } from '@iden3/js-jwz';
|
|
5
5
|
import { byteEncoder } from '../../utils';
|
|
6
6
|
import { AbstractMessageHandler } from './message-handler';
|
|
7
|
+
import { verifyExpiresTime } from './common';
|
|
7
8
|
/**
|
|
8
9
|
* @beta
|
|
9
10
|
* createProposalRequest is a function to create protocol proposal-request protocol message
|
|
@@ -21,7 +22,9 @@ export function createProposalRequest(sender, receiver, opts) {
|
|
|
21
22
|
to: receiver.string(),
|
|
22
23
|
typ: MediaType.PlainMessage,
|
|
23
24
|
type: PROTOCOL_MESSAGE_TYPE.PROPOSAL_REQUEST_MESSAGE_TYPE,
|
|
24
|
-
body: opts
|
|
25
|
+
body: opts,
|
|
26
|
+
created_time: getUnixTimestamp(new Date()),
|
|
27
|
+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
|
|
25
28
|
};
|
|
26
29
|
return request;
|
|
27
30
|
}
|
|
@@ -33,7 +36,7 @@ export function createProposalRequest(sender, receiver, opts) {
|
|
|
33
36
|
* @param {Proposal[]} proposals - proposals
|
|
34
37
|
* @returns `Promise<ProposalRequestMessage>`
|
|
35
38
|
*/
|
|
36
|
-
export function createProposal(sender, receiver, proposals) {
|
|
39
|
+
export function createProposal(sender, receiver, proposals, opts) {
|
|
37
40
|
const uuidv4 = uuid.v4();
|
|
38
41
|
const request = {
|
|
39
42
|
id: uuidv4,
|
|
@@ -44,7 +47,9 @@ export function createProposal(sender, receiver, proposals) {
|
|
|
44
47
|
type: PROTOCOL_MESSAGE_TYPE.PROPOSAL_MESSAGE_TYPE,
|
|
45
48
|
body: {
|
|
46
49
|
proposals: proposals || []
|
|
47
|
-
}
|
|
50
|
+
},
|
|
51
|
+
created_time: getUnixTimestamp(new Date()),
|
|
52
|
+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
|
|
48
53
|
};
|
|
49
54
|
return request;
|
|
50
55
|
}
|
|
@@ -182,6 +187,9 @@ export class CredentialProposalHandler extends AbstractMessageHandler {
|
|
|
182
187
|
if (!proposalRequest.from) {
|
|
183
188
|
throw new Error(`failed request. empty 'from' field`);
|
|
184
189
|
}
|
|
190
|
+
if (!opts?.allowExpiredMessages) {
|
|
191
|
+
verifyExpiresTime(proposalRequest);
|
|
192
|
+
}
|
|
185
193
|
const senderDID = DID.parse(proposalRequest.from);
|
|
186
194
|
const message = await this.handleProposalRequestMessage(proposalRequest);
|
|
187
195
|
const response = byteEncoder.encode(JSON.stringify(message));
|
|
@@ -199,6 +207,9 @@ export class CredentialProposalHandler extends AbstractMessageHandler {
|
|
|
199
207
|
* @inheritdoc ICredentialProposalHandler#handleProposal
|
|
200
208
|
*/
|
|
201
209
|
async handleProposal(proposal, opts) {
|
|
210
|
+
if (!opts?.allowExpiredMessages) {
|
|
211
|
+
verifyExpiresTime(proposal);
|
|
212
|
+
}
|
|
202
213
|
if (opts?.proposalRequest && opts.proposalRequest.from !== proposal.to) {
|
|
203
214
|
throw new Error(`sender of the request is not a target of response - expected ${opts.proposalRequest.from}, given ${proposal.to}`);
|
|
204
215
|
}
|