@arc402/sdk 0.2.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/README.md +184 -0
- package/dist/agent.d.ts +29 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +95 -0
- package/dist/agreement.d.ts +57 -0
- package/dist/agreement.d.ts.map +1 -0
- package/dist/agreement.js +156 -0
- package/dist/capability.d.ts +17 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +19 -0
- package/dist/channel.d.ts +39 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +160 -0
- package/dist/coldstart.d.ts +15 -0
- package/dist/coldstart.d.ts.map +1 -0
- package/dist/coldstart.js +44 -0
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/contractinteraction.d.ts +47 -0
- package/dist/contractinteraction.d.ts.map +1 -0
- package/dist/contractinteraction.js +80 -0
- package/dist/contracts.d.ts +27 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +187 -0
- package/dist/deliverable.d.ts +118 -0
- package/dist/deliverable.d.ts.map +1 -0
- package/dist/deliverable.js +156 -0
- package/dist/dispute-arbitration.d.ts +42 -0
- package/dist/dispute-arbitration.d.ts.map +1 -0
- package/dist/dispute-arbitration.js +160 -0
- package/dist/governance.d.ts +13 -0
- package/dist/governance.d.ts.map +1 -0
- package/dist/governance.js +15 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/intent.d.ts +13 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +26 -0
- package/dist/metadata.d.ts +55 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +106 -0
- package/dist/migration.d.ts +11 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/migration.js +38 -0
- package/dist/multiparty.d.ts +56 -0
- package/dist/multiparty.d.ts.map +1 -0
- package/dist/multiparty.js +86 -0
- package/dist/negotiation-guard.d.ts +20 -0
- package/dist/negotiation-guard.d.ts.map +1 -0
- package/dist/negotiation-guard.js +96 -0
- package/dist/negotiation.d.ts +25 -0
- package/dist/negotiation.d.ts.map +1 -0
- package/dist/negotiation.js +102 -0
- package/dist/policy.d.ts +33 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +72 -0
- package/dist/reputation.d.ts +13 -0
- package/dist/reputation.d.ts.map +1 -0
- package/dist/reputation.js +21 -0
- package/dist/session-manager.d.ts +13 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +102 -0
- package/dist/settlement.d.ts +14 -0
- package/dist/settlement.d.ts.map +1 -0
- package/dist/settlement.js +35 -0
- package/dist/sponsorship.d.ts +17 -0
- package/dist/sponsorship.d.ts.map +1 -0
- package/dist/sponsorship.js +19 -0
- package/dist/trust.d.ts +22 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +52 -0
- package/dist/types.d.ts +391 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +119 -0
- package/dist/wallet.d.ts +31 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +83 -0
- package/dist/watchtower.d.ts +60 -0
- package/dist/watchtower.d.ts.map +1 -0
- package/dist/watchtower.js +93 -0
- package/package.json +30 -0
- package/src/agent.ts +122 -0
- package/src/agreement.ts +236 -0
- package/src/capability.ts +18 -0
- package/src/channel.ts +203 -0
- package/src/coldstart.ts +52 -0
- package/src/context.ts +2 -0
- package/src/contractinteraction.d.ts +47 -0
- package/src/contractinteraction.d.ts.map +1 -0
- package/src/contractinteraction.js +81 -0
- package/src/contractinteraction.js.map +1 -0
- package/src/contractinteraction.ts +157 -0
- package/src/contracts.d.ts +27 -0
- package/src/contracts.d.ts.map +1 -0
- package/src/contracts.js +188 -0
- package/src/contracts.js.map +1 -0
- package/src/contracts.ts +186 -0
- package/src/deliverable.ts +231 -0
- package/src/demos/demo-insurance.ts +148 -0
- package/src/demos/demo-multiagent.ts +197 -0
- package/src/demos/demo-research.ts +124 -0
- package/src/dispute-arbitration.ts +196 -0
- package/src/governance.ts +14 -0
- package/src/index.ts +31 -0
- package/src/intent.ts +22 -0
- package/src/metadata.ts +158 -0
- package/src/migration.ts +43 -0
- package/src/multiparty.ts +132 -0
- package/src/negotiation-guard.ts +125 -0
- package/src/negotiation.ts +135 -0
- package/src/policy.ts +71 -0
- package/src/reputation.ts +20 -0
- package/src/session-manager.ts +80 -0
- package/src/settlement.ts +31 -0
- package/src/sponsorship.ts +18 -0
- package/src/trust.ts +43 -0
- package/src/types.d.ts +391 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.js +113 -0
- package/src/types.js.map +1 -0
- package/src/types.ts +484 -0
- package/src/wallet.ts +86 -0
- package/src/watchtower.ts +124 -0
- package/test/negotiation-signing.test.js +157 -0
- package/test/sdk.test.js +19 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { AbstractSigner, ContractRunner, ethers } from "ethers";
|
|
2
|
+
import type { ChannelState } from "./types";
|
|
3
|
+
import { ChannelClient } from "./channel";
|
|
4
|
+
|
|
5
|
+
const WATCHTOWER_REGISTRY_ABI = [
|
|
6
|
+
"function register(string name, string description, string[] capabilities) external",
|
|
7
|
+
"function getWatchtower(address watchtower) external view returns (tuple(address addr, string name, string description, string[] capabilities, bool active, uint256 registeredAt))",
|
|
8
|
+
"function isRegistered(address watchtower) external view returns (bool)",
|
|
9
|
+
"event WatchtowerRegistered(address indexed watchtower, string name)",
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
const SESSION_CHANNEL_WATCHTOWER_ABI = [
|
|
13
|
+
"function authorizeWatchtower(bytes32 channelId, address watchtower) external",
|
|
14
|
+
"function revokeWatchtower(bytes32 channelId, address watchtower) external",
|
|
15
|
+
"function submitWatchtowerChallenge(bytes32 channelId, bytes latestState, address beneficiary) external",
|
|
16
|
+
"function isWatchtowerAuthorized(bytes32 channelId, address watchtower) external view returns (bool)",
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export interface WatchtowerMetadata {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
capabilities: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface WatchtowerStatus {
|
|
26
|
+
addr: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
capabilities: string[];
|
|
30
|
+
active: boolean;
|
|
31
|
+
registeredAt: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class WatchtowerClient {
|
|
35
|
+
private registry: ethers.Contract;
|
|
36
|
+
private channelContract: ethers.Contract;
|
|
37
|
+
private signer: ethers.Signer | null;
|
|
38
|
+
private _channelClient: ChannelClient;
|
|
39
|
+
|
|
40
|
+
constructor(
|
|
41
|
+
registryAddress: string,
|
|
42
|
+
channelContractAddress: string,
|
|
43
|
+
runner: ContractRunner
|
|
44
|
+
) {
|
|
45
|
+
this.registry = new ethers.Contract(registryAddress, WATCHTOWER_REGISTRY_ABI, runner);
|
|
46
|
+
this.channelContract = new ethers.Contract(channelContractAddress, SESSION_CHANNEL_WATCHTOWER_ABI, runner);
|
|
47
|
+
this.signer = runner instanceof AbstractSigner ? (runner as ethers.Signer) : null;
|
|
48
|
+
this._channelClient = new ChannelClient(channelContractAddress, runner);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Register this node as a watchtower in the WatchtowerRegistry.
|
|
53
|
+
*/
|
|
54
|
+
async registerWatchtower(metadata: WatchtowerMetadata): Promise<{ txHash: string }> {
|
|
55
|
+
if (!this.signer) throw new Error("Signer required");
|
|
56
|
+
const tx = await this.registry.register(metadata.name, metadata.description, metadata.capabilities);
|
|
57
|
+
const receipt = await tx.wait();
|
|
58
|
+
return { txHash: receipt.hash };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Submit a watchtower challenge on behalf of `beneficiary`.
|
|
63
|
+
* The `state` must be a doubly-signed ChannelState with a higher sequenceNumber
|
|
64
|
+
* than the one currently recorded on-chain.
|
|
65
|
+
*/
|
|
66
|
+
async submitChallenge(
|
|
67
|
+
channelId: string,
|
|
68
|
+
state: ChannelState,
|
|
69
|
+
beneficiary: string
|
|
70
|
+
): Promise<{ txHash: string }> {
|
|
71
|
+
if (!this.signer) throw new Error("Signer required");
|
|
72
|
+
const encoded = this._channelClient.encodeChannelState(state);
|
|
73
|
+
const tx = await this.channelContract.submitWatchtowerChallenge(channelId, encoded, beneficiary);
|
|
74
|
+
const receipt = await tx.wait();
|
|
75
|
+
return { txHash: receipt.hash };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the on-chain registration status of a watchtower address.
|
|
80
|
+
*/
|
|
81
|
+
async getWatchtowerStatus(watchtowerAddress: string): Promise<WatchtowerStatus> {
|
|
82
|
+
const raw = await this.registry.getWatchtower(watchtowerAddress);
|
|
83
|
+
return {
|
|
84
|
+
addr: raw.addr,
|
|
85
|
+
name: raw.name,
|
|
86
|
+
description: raw.description,
|
|
87
|
+
capabilities: [...raw.capabilities],
|
|
88
|
+
active: raw.active,
|
|
89
|
+
registeredAt: Number(raw.registeredAt),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Authorize a watchtower to challenge on your behalf for a specific channel.
|
|
95
|
+
*/
|
|
96
|
+
async authorizeWatchtower(channelId: string, watchtower: string): Promise<{ txHash: string }> {
|
|
97
|
+
if (!this.signer) throw new Error("Signer required");
|
|
98
|
+
const tx = await this.channelContract.authorizeWatchtower(channelId, watchtower);
|
|
99
|
+
const receipt = await tx.wait();
|
|
100
|
+
return { txHash: receipt.hash };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Revoke a watchtower's authorization for a channel.
|
|
105
|
+
*/
|
|
106
|
+
async revokeWatchtower(channelId: string, watchtower: string): Promise<{ txHash: string }> {
|
|
107
|
+
if (!this.signer) throw new Error("Signer required");
|
|
108
|
+
const tx = await this.channelContract.revokeWatchtower(channelId, watchtower);
|
|
109
|
+
const receipt = await tx.wait();
|
|
110
|
+
return { txHash: receipt.hash };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Check whether a watchtower is authorized for a channel.
|
|
115
|
+
*/
|
|
116
|
+
async isWatchtowerAuthorized(channelId: string, watchtower: string): Promise<boolean> {
|
|
117
|
+
return this.channelContract.isWatchtowerAuthorized(channelId, watchtower);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Expose ChannelClient for polling in watch loops. */
|
|
121
|
+
get channelClient(): ChannelClient {
|
|
122
|
+
return this._channelClient;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const { ethers } = require('ethers');
|
|
4
|
+
const {
|
|
5
|
+
signNegotiationMessage,
|
|
6
|
+
createSignedProposal,
|
|
7
|
+
parseNegotiationMessage,
|
|
8
|
+
} = require('../dist');
|
|
9
|
+
const { NegotiationGuard } = require('../dist');
|
|
10
|
+
|
|
11
|
+
// Minimal mock ContractRunner + Registry that always returns isRegistered=true
|
|
12
|
+
function makeRunner(isRegistered = true) {
|
|
13
|
+
// NegotiationGuard calls this.registry.isRegistered(addr)
|
|
14
|
+
// We stub it by creating a fake contract
|
|
15
|
+
return { isRegistered };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function makeMockGuard(isRegistered = true, opts = {}) {
|
|
19
|
+
const guard = new NegotiationGuard({
|
|
20
|
+
agentRegistryAddress: '0x0000000000000000000000000000000000000001',
|
|
21
|
+
runner: {},
|
|
22
|
+
...opts,
|
|
23
|
+
});
|
|
24
|
+
// Replace registry with a mock
|
|
25
|
+
guard['registry'] = {
|
|
26
|
+
isRegistered: async () => isRegistered,
|
|
27
|
+
};
|
|
28
|
+
return guard;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const WALLET = ethers.Wallet.createRandom();
|
|
32
|
+
|
|
33
|
+
const BASE_INPUT = {
|
|
34
|
+
from: WALLET.address,
|
|
35
|
+
to: '0x0000000000000000000000000000000000000002',
|
|
36
|
+
serviceType: 'legal.patent-analysis.us.v1',
|
|
37
|
+
price: '50000000000000000',
|
|
38
|
+
token: '0x0000000000000000000000000000000000000000',
|
|
39
|
+
deadline: '2026-03-11T22:00:00Z',
|
|
40
|
+
spec: 'Analyze patent US11234567',
|
|
41
|
+
specHash: '0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
test('sign and verify a PROPOSE message passes NegotiationGuard', async () => {
|
|
45
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
46
|
+
assert.equal(proposal.type, 'PROPOSE');
|
|
47
|
+
assert.ok(proposal.sig.startsWith('0x'));
|
|
48
|
+
assert.ok(proposal.timestamp > 0);
|
|
49
|
+
assert.ok(proposal.expiresAt > proposal.timestamp);
|
|
50
|
+
|
|
51
|
+
const guard = makeMockGuard(true);
|
|
52
|
+
const result = await guard.verify(JSON.stringify(proposal));
|
|
53
|
+
assert.equal(result.valid, true, `expected valid but got error: ${result.error}`);
|
|
54
|
+
assert.equal(result.recoveredSigner.toLowerCase(), WALLET.address.toLowerCase());
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('stale timestamp fails with TIMESTAMP_TOO_OLD', async () => {
|
|
58
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
59
|
+
// Backdate timestamp by 120 seconds (beyond 60s tolerance)
|
|
60
|
+
const stale = { ...proposal, timestamp: proposal.timestamp - 120 };
|
|
61
|
+
// Re-sign with the altered timestamp so signature is valid but timestamp is old
|
|
62
|
+
const { ethers: _ethers } = require('ethers');
|
|
63
|
+
// We just inject a stale timestamp without re-signing — sig will be invalid
|
|
64
|
+
// but timestamp check fires first
|
|
65
|
+
const guard = makeMockGuard(true);
|
|
66
|
+
const result = await guard.verify(JSON.stringify(stale));
|
|
67
|
+
assert.equal(result.valid, false);
|
|
68
|
+
assert.equal(result.error, 'TIMESTAMP_TOO_OLD');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('future timestamp fails with TIMESTAMP_IN_FUTURE', async () => {
|
|
72
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
73
|
+
const future = { ...proposal, timestamp: proposal.timestamp + 120 };
|
|
74
|
+
const guard = makeMockGuard(true);
|
|
75
|
+
const result = await guard.verify(JSON.stringify(future));
|
|
76
|
+
assert.equal(result.valid, false);
|
|
77
|
+
assert.equal(result.error, 'TIMESTAMP_IN_FUTURE');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('wrong signer (from mismatch) fails with INVALID_SIGNATURE', async () => {
|
|
81
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
82
|
+
// Swap from to a different address
|
|
83
|
+
const tampered = {
|
|
84
|
+
...proposal,
|
|
85
|
+
from: '0x0000000000000000000000000000000000000099',
|
|
86
|
+
};
|
|
87
|
+
const guard = makeMockGuard(true);
|
|
88
|
+
const result = await guard.verify(JSON.stringify(tampered));
|
|
89
|
+
assert.equal(result.valid, false);
|
|
90
|
+
assert.equal(result.error, 'INVALID_SIGNATURE');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('replayed nonce fails with NONCE_REPLAYED', async () => {
|
|
94
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
95
|
+
const guard = makeMockGuard(true);
|
|
96
|
+
const first = await guard.verify(JSON.stringify(proposal));
|
|
97
|
+
assert.equal(first.valid, true);
|
|
98
|
+
const second = await guard.verify(JSON.stringify(proposal));
|
|
99
|
+
assert.equal(second.valid, false);
|
|
100
|
+
assert.equal(second.error, 'NONCE_REPLAYED');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('oversized message fails with MESSAGE_TOO_LARGE', async () => {
|
|
104
|
+
const bigSpec = 'x'.repeat(64 * 1024 + 1);
|
|
105
|
+
const guard = makeMockGuard(true);
|
|
106
|
+
const result = await guard.verify(JSON.stringify({ spec: bigSpec }));
|
|
107
|
+
assert.equal(result.valid, false);
|
|
108
|
+
assert.equal(result.error, 'MESSAGE_TOO_LARGE');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('parseNegotiationMessage throws on oversized message', () => {
|
|
112
|
+
const big = JSON.stringify({ type: 'PROPOSE', data: 'x'.repeat(64 * 1024 + 1) });
|
|
113
|
+
assert.throws(() => parseNegotiationMessage(big), /64KB/);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('expired PROPOSE fails with MESSAGE_EXPIRED', async () => {
|
|
117
|
+
const now = Math.floor(Date.now() / 1000);
|
|
118
|
+
// Build a message with expiresAt in the past, but valid timestamp
|
|
119
|
+
const unsigned = {
|
|
120
|
+
type: 'PROPOSE',
|
|
121
|
+
from: WALLET.address,
|
|
122
|
+
to: BASE_INPUT.to,
|
|
123
|
+
serviceType: BASE_INPUT.serviceType,
|
|
124
|
+
price: BASE_INPUT.price,
|
|
125
|
+
token: BASE_INPUT.token,
|
|
126
|
+
deadline: BASE_INPUT.deadline,
|
|
127
|
+
spec: BASE_INPUT.spec,
|
|
128
|
+
specHash: BASE_INPUT.specHash,
|
|
129
|
+
nonce: ethers.hexlify(ethers.randomBytes(16)),
|
|
130
|
+
timestamp: now,
|
|
131
|
+
expiresAt: now - 10, // already expired
|
|
132
|
+
};
|
|
133
|
+
const proposal = await signNegotiationMessage(unsigned, WALLET);
|
|
134
|
+
const guard = makeMockGuard(true);
|
|
135
|
+
const result = await guard.verify(JSON.stringify(proposal));
|
|
136
|
+
assert.equal(result.valid, false);
|
|
137
|
+
assert.equal(result.error, 'MESSAGE_EXPIRED');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test('unregistered signer fails with SIGNER_NOT_REGISTERED', async () => {
|
|
141
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
142
|
+
const guard = makeMockGuard(false); // registry returns false
|
|
143
|
+
const result = await guard.verify(JSON.stringify(proposal));
|
|
144
|
+
assert.equal(result.valid, false);
|
|
145
|
+
assert.equal(result.error, 'SIGNER_NOT_REGISTERED');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('registry downtime fails open (signature-only verification passes)', async () => {
|
|
149
|
+
const proposal = await createSignedProposal(BASE_INPUT, WALLET);
|
|
150
|
+
const guard = makeMockGuard(true);
|
|
151
|
+
// Override registry to throw
|
|
152
|
+
guard['registry'] = { isRegistered: async () => { throw new Error('network error'); } };
|
|
153
|
+
const result = await guard.verify(JSON.stringify(proposal));
|
|
154
|
+
// Should pass with signature-only verification
|
|
155
|
+
assert.equal(result.valid, true);
|
|
156
|
+
assert.equal(result.recoveredSigner.toLowerCase(), WALLET.address.toLowerCase());
|
|
157
|
+
});
|
package/test/sdk.test.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const { createNegotiationProposal, createNegotiationAccept, AgreementStatus, ProviderResponseType, DisputeOutcome, EvidenceType, ArbitrationVote } = require('../dist');
|
|
4
|
+
|
|
5
|
+
test('negotiation helpers generate shaped messages', () => {
|
|
6
|
+
const proposal = createNegotiationProposal({ from: '0x1', to: '0x2', serviceType: 'legal.patent-analysis.us.v1', price: '1', token: '0x0000000000000000000000000000000000000000', deadline: '2026-03-11T22:00:00Z', spec: 'Analyze filing', specHash: '0xabc' });
|
|
7
|
+
assert.equal(proposal.type, 'PROPOSE');
|
|
8
|
+
assert.ok(proposal.nonce.startsWith('0x'));
|
|
9
|
+
const accept = createNegotiationAccept({ from: '0x2', to: '0x1', agreedPrice: '1', agreedDeadline: '2026-03-11T22:00:00Z', refNonce: proposal.nonce });
|
|
10
|
+
assert.equal(accept.refNonce, proposal.nonce);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('enum surfaces include remediation and dispute workflow states', () => {
|
|
14
|
+
assert.equal(AgreementStatus.REVISION_REQUESTED, 6);
|
|
15
|
+
assert.equal(ProviderResponseType.REQUEST_HUMAN_REVIEW, 5);
|
|
16
|
+
assert.equal(DisputeOutcome.PARTIAL_PROVIDER, 4);
|
|
17
|
+
assert.equal(EvidenceType.DELIVERABLE, 2);
|
|
18
|
+
assert.equal(ArbitrationVote.SPLIT, 3);
|
|
19
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"strict": false,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*"],
|
|
16
|
+
"exclude": ["node_modules", "dist", "src/demos"]
|
|
17
|
+
}
|