@pushchain/core 6.0.27-alpha.3 → 6.0.27-alpha.5
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/AGW.md +35 -6
- package/CHANGELOG.md +13 -0
- package/MARKETPLACE.md +206 -0
- package/package.json +2 -1
- package/src/lib/agentic/codec/rules.js +74 -69
- package/src/lib/agentic/codec/universal.js +15 -3
- package/src/lib/agentic/constants.d.ts +36 -1
- package/src/lib/agentic/constants.js +14 -1
- package/src/lib/agentic/contracts/reader.d.ts +21 -0
- package/src/lib/agentic/contracts/reader.js +3 -0
- package/src/lib/agentic/error-messages.d.ts +3 -0
- package/src/lib/agentic/error-messages.js +127 -0
- package/src/lib/agentic/errors.d.ts +12 -3
- package/src/lib/agentic/errors.js +76 -0
- package/src/lib/agentic/management/common.js +6 -0
- package/src/lib/agentic/management/destination.d.ts +5 -0
- package/src/lib/agentic/management/destination.js +32 -0
- package/src/lib/agentic/management/prepare.js +80 -55
- package/src/lib/agentic/management/svm-public.js +13 -4
- package/src/lib/agentic/presets/index.js +8 -9
- package/src/lib/agentic/presets/routes.d.ts +1 -1
- package/src/lib/agentic/presets/routes.js +6 -7
- package/src/lib/agentic/presets/types.d.ts +1 -6
- package/src/lib/agentic/public-rule.js +18 -2
- package/src/lib/constants/index.d.ts +35 -0
- package/src/lib/index.d.ts +4 -0
- package/src/lib/index.js +6 -2
- package/src/lib/job/job.d.ts +35 -0
- package/src/lib/job/job.js +382 -0
- package/src/lib/job/types.d.ts +94 -0
- package/src/lib/job/types.js +3 -0
- package/src/lib/job/watch.d.ts +3 -0
- package/src/lib/job/watch.js +169 -0
- package/src/lib/job-spec/codec.d.ts +18 -0
- package/src/lib/job-spec/codec.js +348 -0
- package/src/lib/job-spec/constants.d.ts +32 -0
- package/src/lib/job-spec/constants.js +36 -0
- package/src/lib/job-spec/helpers.d.ts +19 -0
- package/src/lib/job-spec/helpers.js +138 -0
- package/src/lib/job-spec/index.d.ts +14 -0
- package/src/lib/job-spec/index.js +17 -0
- package/src/lib/job-spec/preview.d.ts +8 -0
- package/src/lib/job-spec/preview.js +298 -0
- package/src/lib/job-spec/read.d.ts +20 -0
- package/src/lib/job-spec/read.js +224 -0
- package/src/lib/job-spec/schema.d.ts +290 -0
- package/src/lib/job-spec/schema.js +70 -0
- package/src/lib/job-spec/types.d.ts +139 -0
- package/src/lib/job-spec/types.js +3 -0
- package/src/lib/market/contracts/AgenticCommerce.d.ts +1026 -0
- package/src/lib/market/contracts/AgenticCommerce.js +1317 -0
- package/src/lib/market/contracts/RulesBindingHook.d.ts +235 -0
- package/src/lib/market/contracts/RulesBindingHook.js +314 -0
- package/src/lib/market/contracts/UniversalMarketplace.d.ts +1770 -0
- package/src/lib/market/contracts/UniversalMarketplace.js +2295 -0
- package/src/lib/market/contracts/UniversalMarketplaceErrors.d.ts +309 -0
- package/src/lib/market/contracts/UniversalMarketplaceErrors.js +416 -0
- package/src/lib/market/contracts/UniversalMarketplaceRules.d.ts +241 -0
- package/src/lib/market/contracts/UniversalMarketplaceRules.js +323 -0
- package/src/lib/market/data.d.ts +8 -0
- package/src/lib/market/data.js +60 -0
- package/src/lib/market/deployment.d.ts +14 -0
- package/src/lib/market/deployment.js +23 -0
- package/src/lib/market/deposit.d.ts +24 -0
- package/src/lib/market/deposit.js +271 -0
- package/src/lib/market/errors.d.ts +13 -0
- package/src/lib/market/errors.js +81 -0
- package/src/lib/market/history.d.ts +6 -0
- package/src/lib/market/history.js +83 -0
- package/src/lib/market/index.d.ts +4 -0
- package/src/lib/market/index.js +12 -0
- package/src/lib/market/kernel-wire.d.ts +15 -0
- package/src/lib/market/kernel-wire.js +41 -0
- package/src/lib/market/market.d.ts +55 -0
- package/src/lib/market/market.js +635 -0
- package/src/lib/market/rules.d.ts +106 -0
- package/src/lib/market/rules.js +293 -0
- package/src/lib/market/runtime.d.ts +35 -0
- package/src/lib/market/runtime.js +130 -0
- package/src/lib/market/types.d.ts +180 -0
- package/src/lib/market/types.js +3 -0
- package/src/lib/orchestrator/internals/errors.d.ts +9 -2
- package/src/lib/orchestrator/internals/errors.js +9 -2
- package/src/lib/orchestrator/internals/push-chain-tx.js +17 -3
- package/src/lib/push-chain/push-chain.d.ts +44 -1
- package/src/lib/push-chain/push-chain.js +23 -3
- package/src/lib/read-state/read-params.d.ts +9 -0
- package/src/lib/read-state/read-params.js +5 -1
- package/src/lib/utils.d.ts +15 -0
- package/src/lib/utils.js +4 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
import { type MoveableToken } from '../constants/tokens';
|
|
3
|
+
import { type MarketSnapshot, type StackRuntime } from './runtime';
|
|
4
|
+
import type { AgentCard, MarketDepositOptions, MarketDepositResult, MarketDepositStep } from './types';
|
|
5
|
+
type LoadCard = (cardId: bigint, at: MarketSnapshot) => Promise<AgentCard>;
|
|
6
|
+
export interface DepositCheckpoint {
|
|
7
|
+
txs: MarketDepositStep[];
|
|
8
|
+
pending?: MarketDepositResult['pending'];
|
|
9
|
+
}
|
|
10
|
+
interface Asset {
|
|
11
|
+
step: MarketDepositStep['step'];
|
|
12
|
+
token?: Address;
|
|
13
|
+
required: bigint;
|
|
14
|
+
originToken?: MoveableToken;
|
|
15
|
+
}
|
|
16
|
+
/** Recover amounts from the block that opened the job, never today's mutable card. */
|
|
17
|
+
export declare function openedDeposit(rt: StackRuntime, jobId: bigint, loadCard: LoadCard): Promise<{
|
|
18
|
+
result: MarketDepositResult;
|
|
19
|
+
assets: Asset[];
|
|
20
|
+
rulesId: Hex;
|
|
21
|
+
}>;
|
|
22
|
+
/** Separate, confirmed top-ups from the signer's Push identity. Does not fund kernel escrow. */
|
|
23
|
+
export declare function depositJob(rt: StackRuntime, jobId: bigint, options: MarketDepositOptions, loadCard: LoadCard, checkpoints: Map<bigint, DepositCheckpoint>): Promise<MarketDepositResult>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openedDeposit = openedDeposit;
|
|
4
|
+
exports.depositJob = depositJob;
|
|
5
|
+
const viem_1 = require("viem");
|
|
6
|
+
const UniversalMarketplace_1 = require("./contracts/UniversalMarketplace");
|
|
7
|
+
const AgenticCommerce_1 = require("./contracts/AgenticCommerce");
|
|
8
|
+
const kernel_wire_1 = require("./kernel-wire");
|
|
9
|
+
const codec_1 = require("../job-spec/codec");
|
|
10
|
+
const helpers_1 = require("../job-spec/helpers");
|
|
11
|
+
const deployments_1 = require("../agentic/deployments");
|
|
12
|
+
const ids_1 = require("../agentic/codec/ids");
|
|
13
|
+
const snapshot_1 = require("../agentic/reads/snapshot");
|
|
14
|
+
const common_1 = require("../agentic/management/common");
|
|
15
|
+
const rules_1 = require("./rules");
|
|
16
|
+
const history_1 = require("./history");
|
|
17
|
+
const tokens_1 = require("../constants/tokens");
|
|
18
|
+
const prc20_address_1 = require("../universal/prc20-address");
|
|
19
|
+
const errors_1 = require("./errors");
|
|
20
|
+
const runtime_1 = require("./runtime");
|
|
21
|
+
const uint256 = (n) => {
|
|
22
|
+
if (typeof n !== 'bigint' || n < BigInt(0) || n >= BigInt(1) << BigInt(256))
|
|
23
|
+
throw new errors_1.MarketError('INVALID_AMOUNT', 'Deposit amounts must fit uint256.');
|
|
24
|
+
};
|
|
25
|
+
function submittedHash(cause, seen = new Set()) {
|
|
26
|
+
if (!cause || typeof cause !== 'object' || seen.has(cause) || seen.size > 16)
|
|
27
|
+
return;
|
|
28
|
+
seen.add(cause);
|
|
29
|
+
const value = cause;
|
|
30
|
+
for (const key of ['gatewayTxHash', 'pendingTransactionHash', 'txHash'])
|
|
31
|
+
if (typeof value[key] === 'string' && value[key])
|
|
32
|
+
return value[key];
|
|
33
|
+
for (const key of ['cause', 'error', 'details']) {
|
|
34
|
+
const found = submittedHash(value[key], seen);
|
|
35
|
+
if (found)
|
|
36
|
+
return found;
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const sameAsset = (a, b) => a === undefined || b === undefined
|
|
41
|
+
? a === b
|
|
42
|
+
: (0, viem_1.getAddress)(a) === (0, viem_1.getAddress)(b);
|
|
43
|
+
/** Recover amounts from the block that opened the job, never today's mutable card. */
|
|
44
|
+
async function openedDeposit(rt, jobId, loadCard) {
|
|
45
|
+
if (typeof jobId !== 'bigint' || jobId < BigInt(1))
|
|
46
|
+
throw new errors_1.MarketError('INVALID_JOB_ID', 'Job IDs are positive bigint values.');
|
|
47
|
+
const s = await (0, runtime_1.snapshot)(rt);
|
|
48
|
+
const d = (0, runtime_1.deployment)(rt);
|
|
49
|
+
const [cardId, version, wallet, rulesId, kernel] = await Promise.all([
|
|
50
|
+
s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'cardOfJob', [jobId]),
|
|
51
|
+
s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'cardVersionOfJob', [jobId]),
|
|
52
|
+
s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'agwOfJob', [jobId]),
|
|
53
|
+
s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'rulesOfJob', [jobId]),
|
|
54
|
+
s.read(d.kernel, kernel_wire_1.KERNEL_READ_ABI, 'getJob', [jobId]),
|
|
55
|
+
]);
|
|
56
|
+
if (!cardId || (0, viem_1.getAddress)(wallet) === viem_1.zeroAddress)
|
|
57
|
+
throw new errors_1.MarketError('NOT_MARKETPLACE_JOB', 'This job was not opened through this marketplace.');
|
|
58
|
+
if (kernel.status !== 0 || kernel.expiredAt <= s.timestamp)
|
|
59
|
+
throw new errors_1.MarketError('WRONG_STATUS', 'Deposit only while the job is Open and unexpired.');
|
|
60
|
+
if ((0, viem_1.getAddress)(kernel.client) !== (0, viem_1.getAddress)(wallet))
|
|
61
|
+
throw new errors_1.MarketError('INCONSISTENT_READ', 'The marketplace wallet differs from the kernel client.');
|
|
62
|
+
let block = rt.jobBlocks?.get(jobId);
|
|
63
|
+
if (block === undefined) {
|
|
64
|
+
const created = await (0, snapshot_1.scanLogs)(rt.agw.reader, {
|
|
65
|
+
address: d.kernel,
|
|
66
|
+
event: (0, viem_1.getAbiItem)({ abi: AgenticCommerce_1.JOB_KERNEL_ABI, name: 'JobCreated' }),
|
|
67
|
+
args: { jobId },
|
|
68
|
+
}, d.startBlock, s.blockNumber);
|
|
69
|
+
if (created.length !== 1 || created[0].blockNumber === null)
|
|
70
|
+
throw new errors_1.MarketError('HISTORY_UNAVAILABLE', 'Could not recover one creation block for this job.');
|
|
71
|
+
block = created[0].blockNumber;
|
|
72
|
+
}
|
|
73
|
+
const logs = await (0, snapshot_1.scanLogs)(rt.agw.reader, {
|
|
74
|
+
address: d.marketplace,
|
|
75
|
+
event: (0, viem_1.getAbiItem)({ abi: UniversalMarketplace_1.MARKETPLACE_ABI, name: 'JobOpened' }),
|
|
76
|
+
args: { cardId, agw: wallet },
|
|
77
|
+
}, block, block);
|
|
78
|
+
const events = logs
|
|
79
|
+
.map((l) => (0, viem_1.decodeEventLog)({
|
|
80
|
+
abi: UniversalMarketplace_1.MARKETPLACE_ABI,
|
|
81
|
+
eventName: 'JobOpened',
|
|
82
|
+
data: l.data,
|
|
83
|
+
topics: l.topics,
|
|
84
|
+
strict: true,
|
|
85
|
+
}).args)
|
|
86
|
+
.filter((e) => e.jobId === jobId);
|
|
87
|
+
if (events.length !== 1)
|
|
88
|
+
throw new errors_1.MarketError('HISTORY_UNAVAILABLE', 'Could not recover one marketplace opening for this job.');
|
|
89
|
+
const opened = events[0];
|
|
90
|
+
const card = await (0, history_1.historicalCard)(rt, cardId, version, block, loadCard);
|
|
91
|
+
if (opened.cardVersion !== version)
|
|
92
|
+
throw new errors_1.MarketError('HISTORY_UNAVAILABLE', 'The opening event does not match the recorded card version.');
|
|
93
|
+
const spec = (0, codec_1.decodeJobSpec)(kernel.description, { format: 'spec' });
|
|
94
|
+
if (!('origin' in spec) ||
|
|
95
|
+
spec.origin !==
|
|
96
|
+
(0, helpers_1.specOrigin)(d.marketplace, cardId, version, opened.principal) ||
|
|
97
|
+
opened.rulesId !== rulesId ||
|
|
98
|
+
(0, viem_1.getAddress)(opened.agw) !== (0, viem_1.getAddress)(wallet) ||
|
|
99
|
+
(0, viem_1.getAddress)(card.provider) !== (0, viem_1.getAddress)(kernel.provider))
|
|
100
|
+
throw new errors_1.MarketError('INCONSISTENT_READ', 'The historical opening does not match the stored job.');
|
|
101
|
+
const token = await s.read(d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'paymentToken');
|
|
102
|
+
if ((0, viem_1.getAddress)(card.paymentToken) !== (0, viem_1.getAddress)(token))
|
|
103
|
+
throw new errors_1.MarketError('TOKEN_MISMATCH', 'The opened card and kernel use different payment tokens.');
|
|
104
|
+
rt.jobBlocks?.set(jobId, block);
|
|
105
|
+
const rules = (0, rules_1.decodeCardRulesWire)(card.rulesBytes);
|
|
106
|
+
return {
|
|
107
|
+
result: {
|
|
108
|
+
jobId,
|
|
109
|
+
wallet: (0, viem_1.getAddress)(wallet),
|
|
110
|
+
cardId,
|
|
111
|
+
cardVersion: version,
|
|
112
|
+
txs: [],
|
|
113
|
+
},
|
|
114
|
+
assets: [
|
|
115
|
+
{
|
|
116
|
+
step: 'PRINCIPAL',
|
|
117
|
+
token: (0, viem_1.getAddress)(rules.assets[rules.principalAsset].token),
|
|
118
|
+
required: opened.principal,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
step: 'PROVIDER_FEE',
|
|
122
|
+
token: (0, viem_1.getAddress)(token),
|
|
123
|
+
required: card.providerFee,
|
|
124
|
+
},
|
|
125
|
+
{ step: 'PC', required: card.rules.maxGasPerCall },
|
|
126
|
+
],
|
|
127
|
+
rulesId,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/** Separate, confirmed top-ups from the signer's Push identity. Does not fund kernel escrow. */
|
|
131
|
+
async function depositJob(rt, jobId, options, loadCard, checkpoints) {
|
|
132
|
+
if (rt.agw.isReadOnly)
|
|
133
|
+
throw new errors_1.MarketError('READ_ONLY', 'Connect a signing wallet to deposit.');
|
|
134
|
+
if ('skipApprovals' in options)
|
|
135
|
+
throw new errors_1.MarketError('INVALID_DEPOSIT_OPTIONS', 'V2 cards grant pinned approvals to the agent; deposit has no owner approval step.');
|
|
136
|
+
if (options.funding !== undefined &&
|
|
137
|
+
!['push', 'origin'].includes(options.funding))
|
|
138
|
+
throw new errors_1.MarketError('INVALID_DEPOSIT_OPTIONS', 'Choose push or origin deposit funding.');
|
|
139
|
+
if (options.funding === 'origin' && rt.agw.signerIsPushNative())
|
|
140
|
+
throw new errors_1.MarketError('INVALID_DEPOSIT_OPTIONS', 'Use push funding for a Push-native signer.');
|
|
141
|
+
if (options.pcAmount !== undefined)
|
|
142
|
+
uint256(options.pcAmount);
|
|
143
|
+
if (options.providerFee !== undefined)
|
|
144
|
+
uint256(options.providerFee);
|
|
145
|
+
const { result, assets, rulesId } = await openedDeposit(rt, jobId, loadCard);
|
|
146
|
+
const previous = checkpoints.get(jobId);
|
|
147
|
+
result.txs = [...(options.resume ?? previous?.txs ?? [])];
|
|
148
|
+
if (previous?.pending &&
|
|
149
|
+
!result.txs.some((t) => sameAsset(t.token, previous.pending?.token)))
|
|
150
|
+
throw new errors_1.MarketError('DEPOSIT_INCOMPLETE', 'A broadcast deposit still needs tracking. Rehydrate its response and pass it as a resume step before sending more.', { ...result, pending: previous.pending });
|
|
151
|
+
const fee = assets[1];
|
|
152
|
+
fee.required = options.providerFee ?? fee.required;
|
|
153
|
+
assets[2].required = options.pcAmount ?? assets[2].required;
|
|
154
|
+
if (assets[0].token === fee.token) {
|
|
155
|
+
assets[0].step = 'PRINCIPAL_AND_FEE';
|
|
156
|
+
assets[0].required += fee.required;
|
|
157
|
+
uint256(assets[0].required);
|
|
158
|
+
assets.splice(1, 1);
|
|
159
|
+
}
|
|
160
|
+
const balance = async (asset, account) => asset.token
|
|
161
|
+
? (await (0, runtime_1.snapshot)(rt)).read(asset.token, viem_1.erc20Abi, 'balanceOf', [
|
|
162
|
+
account,
|
|
163
|
+
])
|
|
164
|
+
: rt.agw.reader.getBalance({ address: account });
|
|
165
|
+
const available = async () => {
|
|
166
|
+
const s = await (0, runtime_1.snapshot)(rt);
|
|
167
|
+
const d = (0, runtime_1.deployment)(rt);
|
|
168
|
+
const job = await s.read(d.kernel, kernel_wire_1.KERNEL_READ_ABI, 'getJob', [jobId]);
|
|
169
|
+
if (job.status !== 0 || job.expiredAt <= s.timestamp)
|
|
170
|
+
throw new errors_1.MarketError('WRONG_STATUS', 'The job is no longer Open and unexpired.');
|
|
171
|
+
const gen = (0, deployments_1.currentGeneration)(rt.agw.network);
|
|
172
|
+
if (!(await s.read(gen.addresses.sessionEngine, gen.contracts.abis.engine, 'isPermissionEnabled', [rulesId, result.wallet])))
|
|
173
|
+
throw new errors_1.MarketError('RULE_NOT_FOUND', 'The job permission is no longer enabled.');
|
|
174
|
+
const actions = await s.read(gen.addresses.sessionEngine, gen.contracts.abis.engine, 'getEnabledActions', [result.wallet, rulesId]);
|
|
175
|
+
if (actions.length !== 1)
|
|
176
|
+
throw new errors_1.MarketError('INCONSISTENT_READ', 'The job permission has an unexpected action count.');
|
|
177
|
+
const config = await s.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getConfig', [
|
|
178
|
+
(0, ids_1.configId)(result.wallet, rulesId, actions[0]),
|
|
179
|
+
result.wallet,
|
|
180
|
+
]);
|
|
181
|
+
if (!config.initialized || config.assets.some((a) => a.spent > BigInt(0)))
|
|
182
|
+
throw new errors_1.MarketError('DEPOSIT_ALREADY_USED', 'The job permission has already moved assets. Review funding manually before adding more.');
|
|
183
|
+
};
|
|
184
|
+
const checkpoint = {
|
|
185
|
+
txs: result.txs,
|
|
186
|
+
pending: previous?.pending,
|
|
187
|
+
};
|
|
188
|
+
checkpoints.set(jobId, checkpoint);
|
|
189
|
+
let submitting;
|
|
190
|
+
try {
|
|
191
|
+
// Uncertain prior receipts must settle before balances can authorize another transfer.
|
|
192
|
+
for (const step of result.txs)
|
|
193
|
+
await (0, common_1.confirmedLogs)(rt.agw, step.tx);
|
|
194
|
+
checkpoint.pending = undefined;
|
|
195
|
+
await available();
|
|
196
|
+
for (const asset of assets) {
|
|
197
|
+
const held = await balance(asset, result.wallet);
|
|
198
|
+
if (held >= asset.required)
|
|
199
|
+
continue;
|
|
200
|
+
if (result.txs.some((t) => sameAsset(t.token, asset.token)))
|
|
201
|
+
throw new errors_1.MarketError('DEPOSIT_BALANCE_CHANGED', 'A confirmed deposit no longer covers its target balance. Review the wallet before sending more.');
|
|
202
|
+
const needed = asset.required - held;
|
|
203
|
+
if (asset.token && options.funding === 'origin') {
|
|
204
|
+
const chain = rt.agw.signerOrigin().chain;
|
|
205
|
+
asset.originToken = (tokens_1.MOVEABLE_TOKENS[chain] ?? []).find((candidate) => {
|
|
206
|
+
try {
|
|
207
|
+
return ((0, viem_1.getAddress)((0, prc20_address_1.getPRC20Address)({ chain, address: candidate.address }, { network: rt.agw.network }).address) === asset.token);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
if (!asset.originToken)
|
|
214
|
+
throw new errors_1.MarketError('TOKEN_ROUTE_UNAVAILABLE', 'This deposit token has no registered route from the connected origin chain. Prefund it on Push or connect its origin.', { chain, token: asset.token });
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const source = (0, viem_1.getAddress)(rt.agw.signerPushAccount());
|
|
218
|
+
if (source === result.wallet || (await balance(asset, source)) < needed)
|
|
219
|
+
throw new errors_1.MarketError('INSUFFICIENT_FUNDS', 'The connected signer’s Push account cannot cover this deposit.', { token: asset.token, required: needed, account: source });
|
|
220
|
+
}
|
|
221
|
+
for (const asset of assets) {
|
|
222
|
+
await available();
|
|
223
|
+
const held = await balance(asset, result.wallet);
|
|
224
|
+
if (held >= asset.required)
|
|
225
|
+
continue;
|
|
226
|
+
const amount = asset.required - held;
|
|
227
|
+
if (result.txs.some((t) => sameAsset(t.token, asset.token)))
|
|
228
|
+
throw new errors_1.MarketError('DEPOSIT_BALANCE_CHANGED', 'A confirmed deposit balance changed before the next step. Review the wallet before sending more.');
|
|
229
|
+
submitting = { step: asset.step, token: asset.token, amount };
|
|
230
|
+
const tx = asset.originToken
|
|
231
|
+
? await rt.agw.execute({ to: result.wallet, funds: { token: asset.originToken, amount } }, { progressHook: options.progressHook })
|
|
232
|
+
: await (0, runtime_1.write)(rt, asset.token
|
|
233
|
+
? {
|
|
234
|
+
target: asset.token,
|
|
235
|
+
value: BigInt(0),
|
|
236
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
237
|
+
abi: viem_1.erc20Abi,
|
|
238
|
+
functionName: 'transfer',
|
|
239
|
+
args: [result.wallet, amount],
|
|
240
|
+
}),
|
|
241
|
+
}
|
|
242
|
+
: { target: result.wallet, value: amount, data: '0x' }, options.progressHook, 'MARKET', true);
|
|
243
|
+
result.txs.push({ step: asset.step, token: asset.token, amount, tx });
|
|
244
|
+
submitting = undefined;
|
|
245
|
+
(0, runtime_1.progress)(rt, options.progressHook, 'MARKET-TX-111', 'Deposit step submitted', { step: asset.step, token: asset.token, amount, txHash: tx.hash });
|
|
246
|
+
await (0, common_1.confirmedLogs)(rt.agw, tx);
|
|
247
|
+
if ((await balance(asset, result.wallet)) < asset.required)
|
|
248
|
+
throw new errors_1.MarketError('DEPOSIT_BALANCE_CHANGED', 'The transfer did not establish the required wallet balance. Review the receipt before retrying.');
|
|
249
|
+
}
|
|
250
|
+
checkpoints.delete(jobId);
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
253
|
+
catch (cause) {
|
|
254
|
+
const txHash = submitting && submittedHash(cause);
|
|
255
|
+
if (submitting && txHash) {
|
|
256
|
+
checkpoint.pending = {
|
|
257
|
+
...submitting,
|
|
258
|
+
txHash,
|
|
259
|
+
chain: options.funding === 'origin' && submitting.token
|
|
260
|
+
? rt.agw.signerOrigin().chain
|
|
261
|
+
: rt.agw.pushChainNamespace,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
throw new errors_1.MarketError('DEPOSIT_INCOMPLETE', 'The deposit did not finish. Resume with the recorded transactions after resolving the cause.', {
|
|
265
|
+
...result,
|
|
266
|
+
...(checkpoint.pending ? { pending: checkpoint.pending } : {}),
|
|
267
|
+
causeCode: cause instanceof errors_1.MarketError ? cause.code : undefined,
|
|
268
|
+
}, cause);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=deposit.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AgenticError } from '../agentic/errors';
|
|
2
|
+
export declare class MarketError extends AgenticError<string> {
|
|
3
|
+
constructor(code: string, message: string, details?: Record<string, unknown>, cause?: unknown);
|
|
4
|
+
}
|
|
5
|
+
export declare class JobError extends MarketError {
|
|
6
|
+
constructor(code: string, message: string, details?: Record<string, unknown>, cause?: unknown);
|
|
7
|
+
}
|
|
8
|
+
export declare class JobSpecError extends MarketError {
|
|
9
|
+
constructor(code: string, message: string, details?: Record<string, unknown>, cause?: unknown);
|
|
10
|
+
}
|
|
11
|
+
export declare function unavailable(feature: string): never;
|
|
12
|
+
/** Inspect provider error chains without parsing human-readable revert messages. */
|
|
13
|
+
export declare function stackError(error: unknown): unknown;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JobSpecError = exports.JobError = exports.MarketError = void 0;
|
|
4
|
+
exports.unavailable = unavailable;
|
|
5
|
+
exports.stackError = stackError;
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const errors_1 = require("../agentic/errors");
|
|
8
|
+
const UniversalMarketplaceErrors_1 = require("./contracts/UniversalMarketplaceErrors");
|
|
9
|
+
const AgenticCommerce_1 = require("./contracts/AgenticCommerce");
|
|
10
|
+
const RulesBindingHook_1 = require("./contracts/RulesBindingHook");
|
|
11
|
+
class MarketError extends errors_1.AgenticError {
|
|
12
|
+
constructor(code, message, details, cause) {
|
|
13
|
+
super(code, message, { userMessage: message, details, cause });
|
|
14
|
+
this.name = 'MarketError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.MarketError = MarketError;
|
|
18
|
+
class JobError extends MarketError {
|
|
19
|
+
constructor(code, message, details, cause) {
|
|
20
|
+
super(code, message, details, cause);
|
|
21
|
+
this.name = 'JobError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.JobError = JobError;
|
|
25
|
+
class JobSpecError extends MarketError {
|
|
26
|
+
constructor(code, message, details, cause) {
|
|
27
|
+
super(code, message, details, cause);
|
|
28
|
+
this.name = 'JobSpecError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.JobSpecError = JobSpecError;
|
|
32
|
+
function unavailable(feature) {
|
|
33
|
+
throw new MarketError('CAPABILITY_UNAVAILABLE', `${feature} is not available in the deployed marketplace v2 stack.`, { feature });
|
|
34
|
+
}
|
|
35
|
+
/** Inspect provider error chains without parsing human-readable revert messages. */
|
|
36
|
+
function stackError(error) {
|
|
37
|
+
if (error instanceof errors_1.AgenticError)
|
|
38
|
+
return error;
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
const submitted = error;
|
|
41
|
+
const recovery = {
|
|
42
|
+
...(submitted?.txHash ? { txHash: submitted.txHash } : {}),
|
|
43
|
+
...(submitted?.pendingTransactionHash
|
|
44
|
+
? { pendingTransactionHash: submitted.pendingTransactionHash }
|
|
45
|
+
: {}),
|
|
46
|
+
...(submitted?.gatewayTxHash
|
|
47
|
+
? { gatewayTxHash: submitted.gatewayTxHash }
|
|
48
|
+
: {}),
|
|
49
|
+
};
|
|
50
|
+
function visit(value, depth) {
|
|
51
|
+
if (!value || typeof value !== 'object' || seen.has(value) || depth > 8)
|
|
52
|
+
return;
|
|
53
|
+
seen.add(value);
|
|
54
|
+
const o = value;
|
|
55
|
+
if (o['code'] === 4001 || o['name'] === 'UserRejectedRequestError')
|
|
56
|
+
return new MarketError('REQUEST_REJECTED', 'The wallet request was cancelled.', undefined, error);
|
|
57
|
+
if (typeof o['data'] === 'string' && /^0x[0-9a-f]+$/i.test(o['data'])) {
|
|
58
|
+
try {
|
|
59
|
+
const decoded = (0, viem_1.decodeErrorResult)({
|
|
60
|
+
abi: [...UniversalMarketplaceErrors_1.MARKET_ERRORS_ABI, ...AgenticCommerce_1.JOB_KERNEL_ABI, ...RulesBindingHook_1.RULES_HOOK_ABI],
|
|
61
|
+
data: o['data'],
|
|
62
|
+
});
|
|
63
|
+
const code = decoded.errorName
|
|
64
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
65
|
+
.toUpperCase();
|
|
66
|
+
return new MarketError(code, `The contract rejected the request: ${decoded.errorName}.`, { decodedError: decoded, ...recovery }, error);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* This value is not a known stack revert; retain the provider cause. */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const key of ['cause', 'error', 'data']) {
|
|
73
|
+
const found = visit(o[key], depth + 1);
|
|
74
|
+
if (found)
|
|
75
|
+
return found;
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
return visit(error, 0) ?? error;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type MarketSnapshot, type StackRuntime } from './runtime';
|
|
2
|
+
import type { AgentCard } from './types';
|
|
3
|
+
/** Exact deposit-critical fields from an emitted version, including same-block updates.
|
|
4
|
+
* Event content hashes, immutable provider/chain and the kernel token bind the recovered input.
|
|
5
|
+
*/
|
|
6
|
+
export declare function historicalCard(rt: StackRuntime, cardId: bigint, version: bigint, openedAt: bigint, load: (cardId: bigint, at: MarketSnapshot) => Promise<AgentCard>): Promise<Pick<AgentCard, 'version' | 'provider' | 'paymentToken' | 'providerFee' | 'rulesBytes' | 'rules'>>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.historicalCard = historicalCard;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const snapshot_1 = require("../agentic/reads/snapshot");
|
|
6
|
+
const UniversalMarketplace_1 = require("./contracts/UniversalMarketplace");
|
|
7
|
+
const rules_1 = require("./rules");
|
|
8
|
+
const data_1 = require("./data");
|
|
9
|
+
const errors_1 = require("./errors");
|
|
10
|
+
const runtime_1 = require("./runtime");
|
|
11
|
+
/** Exact deposit-critical fields from an emitted version, including same-block updates.
|
|
12
|
+
* Event content hashes, immutable provider/chain and the kernel token bind the recovered input.
|
|
13
|
+
*/
|
|
14
|
+
async function historicalCard(rt, cardId, version, openedAt, load) {
|
|
15
|
+
let originalCause;
|
|
16
|
+
try {
|
|
17
|
+
const card = await load(cardId, await (0, runtime_1.snapshot)(rt, openedAt));
|
|
18
|
+
if (card.version === version)
|
|
19
|
+
return card;
|
|
20
|
+
}
|
|
21
|
+
catch (cause) {
|
|
22
|
+
originalCause = cause;
|
|
23
|
+
}
|
|
24
|
+
const d = (0, runtime_1.deployment)(rt);
|
|
25
|
+
const fail = (cause) => {
|
|
26
|
+
throw new errors_1.MarketError('HISTORY_UNAVAILABLE', 'Could not authenticate the exact opened card version from historical state or transaction input.', { cardId, cardVersion: version, openedAt }, cause ?? originalCause);
|
|
27
|
+
};
|
|
28
|
+
if (!rt.agw.reader.getTransaction)
|
|
29
|
+
return fail();
|
|
30
|
+
const name = version === BigInt(1) ? 'AgentCardRegistered' : 'AgentCardUpdated';
|
|
31
|
+
const records = await (0, snapshot_1.scanLogs)(rt.agw.reader, {
|
|
32
|
+
address: d.marketplace,
|
|
33
|
+
event: (0, viem_1.getAbiItem)({ abi: UniversalMarketplace_1.MARKETPLACE_ABI, name }),
|
|
34
|
+
args: { cardId },
|
|
35
|
+
}, d.startBlock, openedAt);
|
|
36
|
+
const matches = records
|
|
37
|
+
.map((log) => ({
|
|
38
|
+
log,
|
|
39
|
+
event: (0, viem_1.decodeEventLog)({
|
|
40
|
+
abi: UniversalMarketplace_1.MARKETPLACE_ABI,
|
|
41
|
+
eventName: name,
|
|
42
|
+
data: log.data,
|
|
43
|
+
topics: log.topics,
|
|
44
|
+
strict: true,
|
|
45
|
+
}).args,
|
|
46
|
+
}))
|
|
47
|
+
.filter(({ event }) => !('version' in event) || event.version === version);
|
|
48
|
+
if (matches.length !== 1)
|
|
49
|
+
return fail();
|
|
50
|
+
const { log, event } = matches[0];
|
|
51
|
+
if (!log.transactionHash || log.blockNumber === null)
|
|
52
|
+
return fail();
|
|
53
|
+
const tx = await rt.agw.reader.getTransaction({ hash: log.transactionHash });
|
|
54
|
+
if (tx.blockNumber !== log.blockNumber)
|
|
55
|
+
return fail();
|
|
56
|
+
// The chain and provider cannot change on update. Do not decode today's potentially malformed template.
|
|
57
|
+
const current = await (await (0, runtime_1.snapshot)(rt)).read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'getAgentCard', [cardId]);
|
|
58
|
+
const fn = version === BigInt(1) ? 'registerAgentCard' : 'updateAgentCard';
|
|
59
|
+
const candidates = (0, data_1.embeddedCalls)(tx.input, UniversalMarketplace_1.MARKETPLACE_ABI, fn).filter((args) => {
|
|
60
|
+
const i = version === BigInt(1) ? 0 : 1;
|
|
61
|
+
const c = args[i];
|
|
62
|
+
return ((i === 0 || args[0] === cardId) &&
|
|
63
|
+
c.chainNamespace === current.card.chainNamespace &&
|
|
64
|
+
(0, viem_1.getAddress)(c.paymentToken) === (0, viem_1.getAddress)(current.card.paymentToken) &&
|
|
65
|
+
c.providerFee === event.providerFee &&
|
|
66
|
+
(0, viem_1.keccak256)(args[i + 1]) === event.rulesHash &&
|
|
67
|
+
(0, viem_1.keccak256)(args[i + 2]) === event.jobSpecHash);
|
|
68
|
+
});
|
|
69
|
+
// Identical byte sequences may appear more than once in a wrapper. Hash-bound content is identical.
|
|
70
|
+
if (!candidates.length)
|
|
71
|
+
return fail();
|
|
72
|
+
const i = version === BigInt(1) ? 0 : 1;
|
|
73
|
+
const rulesBytes = candidates[0][i + 1];
|
|
74
|
+
return {
|
|
75
|
+
version,
|
|
76
|
+
provider: (0, viem_1.getAddress)(current.card.provider),
|
|
77
|
+
paymentToken: (0, viem_1.getAddress)(current.card.paymentToken),
|
|
78
|
+
providerFee: event.providerFee,
|
|
79
|
+
rulesBytes,
|
|
80
|
+
rules: (0, rules_1.decodeAgentCardRules)(rulesBytes),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decodeAgentCardRules = exports.encodeAgentCardRules = exports.validateAgentCardRules = exports.JobSpecError = exports.JobError = exports.MarketError = void 0;
|
|
4
|
+
var errors_1 = require("./errors");
|
|
5
|
+
Object.defineProperty(exports, "MarketError", { enumerable: true, get: function () { return errors_1.MarketError; } });
|
|
6
|
+
Object.defineProperty(exports, "JobError", { enumerable: true, get: function () { return errors_1.JobError; } });
|
|
7
|
+
Object.defineProperty(exports, "JobSpecError", { enumerable: true, get: function () { return errors_1.JobSpecError; } });
|
|
8
|
+
var rules_1 = require("./rules");
|
|
9
|
+
Object.defineProperty(exports, "validateAgentCardRules", { enumerable: true, get: function () { return rules_1.validateAgentCardRules; } });
|
|
10
|
+
Object.defineProperty(exports, "encodeAgentCardRules", { enumerable: true, get: function () { return rules_1.encodeAgentCardRules; } });
|
|
11
|
+
Object.defineProperty(exports, "decodeAgentCardRules", { enumerable: true, get: function () { return rules_1.decodeAgentCardRules; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Abi, type Address, type Hex } from 'viem';
|
|
2
|
+
export declare const CREATE_JOB_SELECTOR: `0x${string}`;
|
|
3
|
+
/** Solidity string(description) carries arbitrary ABI bytes, not UTF-8 text. */
|
|
4
|
+
export declare const KERNEL_READ_ABI: Abi;
|
|
5
|
+
export declare function encodeCreateJob(provider: Address, evaluator: Address, expiredAt: number, payload: {
|
|
6
|
+
jobSpec?: Hex;
|
|
7
|
+
description?: string;
|
|
8
|
+
}, hook: Address): Hex;
|
|
9
|
+
export declare function decodeCreateJob(data: Hex): {
|
|
10
|
+
provider: Address;
|
|
11
|
+
evaluator: Address;
|
|
12
|
+
expiredAt: bigint;
|
|
13
|
+
description: Hex;
|
|
14
|
+
hook: Address;
|
|
15
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KERNEL_READ_ABI = exports.CREATE_JOB_SELECTOR = void 0;
|
|
4
|
+
exports.encodeCreateJob = encodeCreateJob;
|
|
5
|
+
exports.decodeCreateJob = decodeCreateJob;
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const AgenticCommerce_1 = require("./contracts/AgenticCommerce");
|
|
8
|
+
const errors_1 = require("./errors");
|
|
9
|
+
const create = (0, viem_1.getAbiItem)({ abi: AgenticCommerce_1.JOB_KERNEL_ABI, name: 'createJob' });
|
|
10
|
+
exports.CREATE_JOB_SELECTOR = (0, viem_1.toFunctionSelector)(create);
|
|
11
|
+
const inputs = create.inputs.map((p) => p.name === 'description' ? { ...p, type: 'bytes' } : p);
|
|
12
|
+
/** Solidity string(description) carries arbitrary ABI bytes, not UTF-8 text. */
|
|
13
|
+
exports.KERNEL_READ_ABI = AgenticCommerce_1.JOB_KERNEL_ABI.map((item) => item.type === 'function' && item.name === 'getJob'
|
|
14
|
+
? {
|
|
15
|
+
...item,
|
|
16
|
+
outputs: item.outputs.map((p) => ({
|
|
17
|
+
...p,
|
|
18
|
+
components: p.components.map((c) => c.name === 'description' ? { ...c, type: 'bytes' } : c),
|
|
19
|
+
})),
|
|
20
|
+
}
|
|
21
|
+
: item);
|
|
22
|
+
function encodeCreateJob(provider, evaluator, expiredAt, payload, hook) {
|
|
23
|
+
if (payload.jobSpec && payload.description !== undefined)
|
|
24
|
+
throw new errors_1.JobError('INVALID_JOB', 'Use jobSpec or description, not both.');
|
|
25
|
+
const bytes = payload.jobSpec ?? (0, viem_1.stringToHex)(payload.description ?? '');
|
|
26
|
+
return (exports.CREATE_JOB_SELECTOR +
|
|
27
|
+
(0, viem_1.encodeAbiParameters)(inputs, [
|
|
28
|
+
provider,
|
|
29
|
+
evaluator,
|
|
30
|
+
BigInt(expiredAt),
|
|
31
|
+
bytes,
|
|
32
|
+
hook,
|
|
33
|
+
]).slice(2));
|
|
34
|
+
}
|
|
35
|
+
function decodeCreateJob(data) {
|
|
36
|
+
if (data.slice(0, 10).toLowerCase() !== exports.CREATE_JOB_SELECTOR)
|
|
37
|
+
throw new errors_1.JobError('INVALID_JOB', 'Expected the deployed kernel createJob selector.');
|
|
38
|
+
const [provider, evaluator, expiredAt, description, hook] = (0, viem_1.decodeAbiParameters)(inputs, ('0x' + data.slice(10)));
|
|
39
|
+
return { provider, evaluator, expiredAt, description, hook };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=kernel-wire.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
import { type StackRuntime } from './runtime';
|
|
3
|
+
import type { AgentCard, AgentCardInput, AgentCardSummary, JobPlan, MarketNamespace, MarketPreviewOptions, MarketWriteOptions, MarketDepositOptions, MarketOpenOptions } from './types';
|
|
4
|
+
export declare class MarketNamespaceImpl implements MarketNamespace {
|
|
5
|
+
private readonly rt;
|
|
6
|
+
constructor(rt: StackRuntime);
|
|
7
|
+
private readonly deposits;
|
|
8
|
+
private readonly depositCheckpoints;
|
|
9
|
+
private viewAt;
|
|
10
|
+
private summaryAt;
|
|
11
|
+
private cardAt;
|
|
12
|
+
card(cardId: bigint): Promise<AgentCard>;
|
|
13
|
+
cards(options?: {
|
|
14
|
+
provider?: Address;
|
|
15
|
+
chain?: string;
|
|
16
|
+
active?: boolean;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
cards: AgentCardSummary[];
|
|
19
|
+
}>;
|
|
20
|
+
job(jobId: bigint): Promise<{
|
|
21
|
+
cardId: bigint;
|
|
22
|
+
cardVersion: bigint;
|
|
23
|
+
wallet: Address;
|
|
24
|
+
rulesId: Hex;
|
|
25
|
+
}>;
|
|
26
|
+
activeJob(wallet: Address): Promise<{
|
|
27
|
+
jobId: bigint;
|
|
28
|
+
}>;
|
|
29
|
+
preview(cardId: bigint, options: MarketPreviewOptions): Promise<JobPlan>;
|
|
30
|
+
openJob(plan: JobPlan, options?: MarketOpenOptions): Promise<{
|
|
31
|
+
jobId: bigint;
|
|
32
|
+
wallet: `0x${string}`;
|
|
33
|
+
rulesId: Hex;
|
|
34
|
+
tx: import("../orchestrator/orchestrator.types").UniversalTxResponse;
|
|
35
|
+
}>;
|
|
36
|
+
private openedResult;
|
|
37
|
+
private verifyOpening;
|
|
38
|
+
deposit(jobId: bigint, options?: MarketDepositOptions): Promise<import("./types").MarketDepositResult>;
|
|
39
|
+
readonly agent: {
|
|
40
|
+
card: () => Promise<AgentCard | undefined>;
|
|
41
|
+
register: (card: AgentCardInput, options: Parameters<MarketNamespace["agent"]["register"]>[1]) => Promise<{
|
|
42
|
+
cardId: bigint;
|
|
43
|
+
version: bigint;
|
|
44
|
+
tx: import("../orchestrator/orchestrator.types").UniversalTxResponse;
|
|
45
|
+
}>;
|
|
46
|
+
update: (cardId: bigint, card: AgentCardInput, options: Parameters<MarketNamespace["agent"]["update"]>[2]) => Promise<{
|
|
47
|
+
cardId: bigint;
|
|
48
|
+
version: bigint;
|
|
49
|
+
tx: import("../orchestrator/orchestrator.types").UniversalTxResponse;
|
|
50
|
+
}>;
|
|
51
|
+
setActive: (cardId: bigint, active: boolean, options?: MarketWriteOptions) => Promise<import("../orchestrator/orchestrator.types").UniversalTxResponse>;
|
|
52
|
+
};
|
|
53
|
+
private assertProvider;
|
|
54
|
+
private cardWrite;
|
|
55
|
+
}
|