@haven_ai/sdk 0.6.0-alpha.0 → 0.8.0-alpha.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 +33 -16
- package/dist/{base64-cD9kR4JL.d.cts → base64-znjJJQqu.d.cts} +457 -18
- package/dist/{base64-cD9kR4JL.d.ts → base64-znjJJQqu.d.ts} +457 -18
- package/dist/{chunk-63GPTEEY.js → chunk-H4APV67M.js} +90 -9
- package/dist/chunk-H4APV67M.js.map +1 -0
- package/dist/{chunk-S42QSWJY.cjs → chunk-HX34HOW4.cjs} +93 -8
- package/dist/chunk-HX34HOW4.cjs.map +1 -0
- package/dist/{chunk-3WSEX3GW.js → chunk-UXULZ3ZY.js} +186 -17
- package/dist/chunk-UXULZ3ZY.js.map +1 -0
- package/dist/{chunk-CK4NLLMO.cjs → chunk-WJFDXCYP.cjs} +223 -40
- package/dist/chunk-WJFDXCYP.cjs.map +1 -0
- package/dist/edge.cjs +317 -106
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.d.cts +268 -2
- package/dist/edge.d.ts +268 -2
- package/dist/edge.js +196 -45
- package/dist/edge.js.map +1 -1
- package/dist/index.cjs +957 -391
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +181 -40
- package/dist/index.d.ts +181 -40
- package/dist/index.js +658 -113
- package/dist/index.js.map +1 -1
- package/dist/test-support.cjs +18 -18
- package/dist/test-support.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3WSEX3GW.js.map +0 -1
- package/dist/chunk-63GPTEEY.js.map +0 -1
- package/dist/chunk-CK4NLLMO.cjs.map +0 -1
- package/dist/chunk-S42QSWJY.cjs.map +0 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkHX34HOW4_cjs = require('./chunk-HX34HOW4.cjs');
|
|
4
4
|
var viem = require('viem');
|
|
5
5
|
var crypto = require('crypto');
|
|
6
|
+
var secp256k1 = require('@noble/curves/secp256k1');
|
|
7
|
+
var accounts = require('viem/accounts');
|
|
6
8
|
|
|
7
9
|
var TYPED_DATA_NOT_ALLOWED = "TYPED_DATA_NOT_ALLOWED";
|
|
8
|
-
var HavenTypedDataRefusedError = class extends
|
|
10
|
+
var HavenTypedDataRefusedError = class extends chunkHX34HOW4_cjs.HavenSigningError {
|
|
9
11
|
constructor(message) {
|
|
10
12
|
super(message);
|
|
11
13
|
this.code = TYPED_DATA_NOT_ALLOWED;
|
|
@@ -46,7 +48,7 @@ function assertBoundDirectPaymentUserOp(typedData, delegateAddress) {
|
|
|
46
48
|
`This signer only signs direct payments on chains the delegation rail has pinned contracts for (${[...DIRECT_PAYMENT_CHAIN_IDS].join(", ")}); this typed data names chain ${String(domain.chainId)}. Refusing.`
|
|
47
49
|
);
|
|
48
50
|
}
|
|
49
|
-
const ownAccount =
|
|
51
|
+
const ownAccount = chunkHX34HOW4_cjs.deriveDelegateAccountAddress(delegateAddress);
|
|
50
52
|
const sender = typeof message.sender === "string" ? message.sender : "";
|
|
51
53
|
if (sender.toLowerCase() !== ownAccount.toLowerCase()) {
|
|
52
54
|
throw new HavenTypedDataRefusedError(
|
|
@@ -76,9 +78,9 @@ function assertBoundDirectPaymentUserOp(typedData, delegateAddress) {
|
|
|
76
78
|
"This UserOperation's execute() call does not re-encode to the exact callData bytes (trailing or non-canonical bytes). Refusing."
|
|
77
79
|
);
|
|
78
80
|
}
|
|
79
|
-
if (decoded.target.toLowerCase() !==
|
|
81
|
+
if (decoded.target.toLowerCase() !== chunkHX34HOW4_cjs.DELEGATION_MANAGER.toLowerCase()) {
|
|
80
82
|
throw new HavenTypedDataRefusedError(
|
|
81
|
-
`This UserOperation's execute() calls ${decoded.target}, not the DelegationManager (${
|
|
83
|
+
`This UserOperation's execute() calls ${decoded.target}, not the DelegationManager (${chunkHX34HOW4_cjs.DELEGATION_MANAGER}). A direct payment only ever redeems the agent's own budget delegation \u2014 refusing what looks like a self-call (e.g. transferOwnership, updateSigners, upgradeToAndCall) or a call to an unrelated contract.`
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
if (decoded.value !== 0n) {
|
|
@@ -87,20 +89,20 @@ function assertBoundDirectPaymentUserOp(typedData, delegateAddress) {
|
|
|
87
89
|
);
|
|
88
90
|
}
|
|
89
91
|
try {
|
|
90
|
-
|
|
92
|
+
chunkHX34HOW4_cjs.assertRedeemsOwnBudgetDelegation(decoded.callData, ownAccount);
|
|
91
93
|
} catch (err) {
|
|
92
94
|
throw new HavenTypedDataRefusedError(err instanceof Error ? err.message : String(err));
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
function assertOwnSettlementChild(typedData, expectation, delegateAddress) {
|
|
96
98
|
try {
|
|
97
|
-
|
|
99
|
+
chunkHX34HOW4_cjs.verifySettlementChild(typedData, {
|
|
98
100
|
...expectation,
|
|
99
|
-
delegatorAccount:
|
|
101
|
+
delegatorAccount: chunkHX34HOW4_cjs.deriveDelegateAccountAddress(delegateAddress)
|
|
100
102
|
});
|
|
101
103
|
} catch (err) {
|
|
102
104
|
if (err instanceof HavenTypedDataRefusedError) throw err;
|
|
103
|
-
if (err instanceof
|
|
105
|
+
if (err instanceof chunkHX34HOW4_cjs.HavenSigningError) throw new HavenTypedDataRefusedError(err.message);
|
|
104
106
|
throw new HavenTypedDataRefusedError(
|
|
105
107
|
`Refusing to sign the x402 settlement child: it is malformed (${err instanceof Error ? err.message : String(err)}).`
|
|
106
108
|
);
|
|
@@ -129,7 +131,7 @@ function assertFundingLegPaysDelegate(typedData, expected) {
|
|
|
129
131
|
try {
|
|
130
132
|
const { args: executeArgs } = viem.decodeFunctionData({ abi: EXECUTE_ABI, data: message.callData });
|
|
131
133
|
const inner = executeArgs[0].callData;
|
|
132
|
-
const { args } = viem.decodeFunctionData({ abi:
|
|
134
|
+
const { args } = viem.decodeFunctionData({ abi: chunkHX34HOW4_cjs.REDEEM_DELEGATIONS_ABI, data: inner });
|
|
133
135
|
const executions = args[2];
|
|
134
136
|
executionCallData = executions[0];
|
|
135
137
|
} catch {
|
|
@@ -248,7 +250,7 @@ var TRANSFER_WITH_AUTHORIZATION_TYPES = {
|
|
|
248
250
|
function sweepUsdcAddress(chainId) {
|
|
249
251
|
const address = USDC_ADDRESS_BY_CHAIN[chainId];
|
|
250
252
|
if (!address) {
|
|
251
|
-
throw new
|
|
253
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError(
|
|
252
254
|
`Sweep is not supported on chain ${chainId}. Supported: ${SWEEPABLE_CHAIN_IDS.join(", ")}.`
|
|
253
255
|
);
|
|
254
256
|
}
|
|
@@ -257,7 +259,7 @@ function sweepUsdcAddress(chainId) {
|
|
|
257
259
|
function sweepUsdcDomain(chainId) {
|
|
258
260
|
const domain = USDC_EIP712_DOMAIN_BY_CHAIN[chainId];
|
|
259
261
|
if (!domain) {
|
|
260
|
-
throw new
|
|
262
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError(
|
|
261
263
|
`Sweep is not supported on chain ${chainId}. Supported: ${SWEEPABLE_CHAIN_IDS.join(", ")}.`
|
|
262
264
|
);
|
|
263
265
|
}
|
|
@@ -270,12 +272,12 @@ function buildSweepTypedData(auth) {
|
|
|
270
272
|
const domain = sweepUsdcDomain(auth.chainId);
|
|
271
273
|
const expectedToken = sweepUsdcAddress(auth.chainId);
|
|
272
274
|
if (!sameAddress(auth.token, expectedToken)) {
|
|
273
|
-
throw new
|
|
275
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError(
|
|
274
276
|
`Sweep token ${auth.token} is not the canonical USDC contract for chain ${auth.chainId}.`
|
|
275
277
|
);
|
|
276
278
|
}
|
|
277
279
|
if (!/^0x[0-9a-fA-F]{64}$/.test(auth.nonce)) {
|
|
278
|
-
throw new
|
|
280
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError("Sweep nonce must be a 0x-prefixed 32-byte hex string.");
|
|
279
281
|
}
|
|
280
282
|
return {
|
|
281
283
|
domain,
|
|
@@ -396,7 +398,6 @@ function normalizePaymentRequired(value) {
|
|
|
396
398
|
};
|
|
397
399
|
}
|
|
398
400
|
var SUPPORTED_X402_NETWORKS = {
|
|
399
|
-
"eip155:100": "Gnosis Chain",
|
|
400
401
|
"eip155:8453": "Base",
|
|
401
402
|
"base": "Base",
|
|
402
403
|
"eip155:84532": "Base Sepolia",
|
|
@@ -408,11 +409,6 @@ var STANDARD_X402_NETWORKS = {
|
|
|
408
409
|
"eip155:84532": "base-sepolia",
|
|
409
410
|
"base-sepolia": "base-sepolia"
|
|
410
411
|
};
|
|
411
|
-
var GNOSIS_TOKENS = {
|
|
412
|
-
"0x0000000000000000000000000000000000000000": { symbol: "xDAI", decimals: 18 },
|
|
413
|
-
"0xcb444e90d8198415266c6a2724b7900fb12fc56e": { symbol: "EURe", decimals: 18 },
|
|
414
|
-
"0x2a22f9c3b484c3629090feed35f17ff8f88f76f0": { symbol: "USDC.e", decimals: 6 }
|
|
415
|
-
};
|
|
416
412
|
var BASE_TOKENS = {
|
|
417
413
|
"0x0000000000000000000000000000000000000000": { symbol: "ETH", decimals: 18 },
|
|
418
414
|
"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": { symbol: "USDC", decimals: 6 }
|
|
@@ -422,12 +418,10 @@ var BASE_SEPOLIA_TOKENS = {
|
|
|
422
418
|
"0x036cbd53842c5426634e7929541ec2318f3dcf7e": { symbol: "USDC", decimals: 6 }
|
|
423
419
|
};
|
|
424
420
|
var ALL_TOKENS = {
|
|
425
|
-
...GNOSIS_TOKENS,
|
|
426
421
|
...BASE_TOKENS,
|
|
427
422
|
...BASE_SEPOLIA_TOKENS
|
|
428
423
|
};
|
|
429
424
|
var NETWORK_TOKENS = {
|
|
430
|
-
"eip155:100": GNOSIS_TOKENS,
|
|
431
425
|
"eip155:8453": BASE_TOKENS,
|
|
432
426
|
"base": BASE_TOKENS,
|
|
433
427
|
"eip155:84532": BASE_SEPOLIA_TOKENS,
|
|
@@ -762,11 +756,15 @@ function encodePaymentProof(receipt) {
|
|
|
762
756
|
}
|
|
763
757
|
function resolveTokenFromAddress(address, network) {
|
|
764
758
|
const lower = address.toLowerCase();
|
|
765
|
-
if (network
|
|
766
|
-
return NETWORK_TOKENS[network][lower] ?? null;
|
|
767
|
-
}
|
|
759
|
+
if (network) return NETWORK_TOKENS[network]?.[lower] ?? null;
|
|
768
760
|
return ALL_TOKENS[lower] ?? null;
|
|
769
761
|
}
|
|
762
|
+
function resolveTokenBySymbol(chainId, symbol) {
|
|
763
|
+
const table = NETWORK_TOKENS[`eip155:${chainId}`];
|
|
764
|
+
if (!table) return null;
|
|
765
|
+
const hit = Object.entries(table).find(([, token]) => token.symbol === symbol);
|
|
766
|
+
return hit ? { ...hit[1] } : null;
|
|
767
|
+
}
|
|
770
768
|
function stableStringify2(value) {
|
|
771
769
|
if (value === null || typeof value !== "object") {
|
|
772
770
|
const primitive = JSON.stringify(value);
|
|
@@ -779,7 +777,7 @@ function stableStringify2(value) {
|
|
|
779
777
|
}
|
|
780
778
|
|
|
781
779
|
// src/client-identity.ts
|
|
782
|
-
var SDK_VERSION = "0.
|
|
780
|
+
var SDK_VERSION = "0.8.0-alpha.0";
|
|
783
781
|
var HAVEN_CLIENT_HEADER = "X-Haven-Client";
|
|
784
782
|
function havenClientIdentity(pkg, version) {
|
|
785
783
|
return `${pkg}/${version}`;
|
|
@@ -801,6 +799,177 @@ function readClientUpdate(value) {
|
|
|
801
799
|
notes_url: typeof v.notes_url === "string" ? v.notes_url : null
|
|
802
800
|
};
|
|
803
801
|
}
|
|
802
|
+
var HALF_N = BigInt("0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0");
|
|
803
|
+
function hexBytes(value, bytes, what) {
|
|
804
|
+
if (!/^0x[0-9a-fA-F]+$/.test(value) || value.length !== 2 + bytes * 2) {
|
|
805
|
+
throw new Error(`${what} must be a 0x-prefixed ${bytes}-byte hex string`);
|
|
806
|
+
}
|
|
807
|
+
return value.slice(2);
|
|
808
|
+
}
|
|
809
|
+
function addressFromKey(privateKey) {
|
|
810
|
+
try {
|
|
811
|
+
return accounts.privateKeyToAddress(`0x${hexBytes(privateKey, 32, "private key")}`);
|
|
812
|
+
} catch (err) {
|
|
813
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError(
|
|
814
|
+
`Invalid private key: ${err instanceof Error ? err.message : String(err)}`
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function signHash(privateKey, hash) {
|
|
819
|
+
try {
|
|
820
|
+
const { r, s, recovery } = secp256k1.secp256k1.sign(hexBytes(hash, 32, "hash"), hexBytes(privateKey, 32, "private key"), { lowS: true });
|
|
821
|
+
return viem.serializeSignature({
|
|
822
|
+
r: `0x${r.toString(16).padStart(64, "0")}`,
|
|
823
|
+
s: `0x${s.toString(16).padStart(64, "0")}`,
|
|
824
|
+
yParity: recovery
|
|
825
|
+
});
|
|
826
|
+
} catch (err) {
|
|
827
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError(
|
|
828
|
+
`Failed to sign hash: ${err instanceof Error ? err.message : String(err)}`
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
function verifySignature(hash, signature, expectedAddress) {
|
|
833
|
+
try {
|
|
834
|
+
const sig = hexBytes(signature, 65, "signature");
|
|
835
|
+
const hashHex = hexBytes(hash, 32, "hash");
|
|
836
|
+
if (BigInt(`0x${sig.slice(64, 128)}`) > HALF_N) return false;
|
|
837
|
+
const yParityOrV = Number.parseInt(sig.slice(128), 16);
|
|
838
|
+
const recoveryBit = yParityOrV === 0 || yParityOrV === 27 ? 0 : yParityOrV === 1 || yParityOrV === 28 ? 1 : -1;
|
|
839
|
+
if (recoveryBit < 0) return false;
|
|
840
|
+
const publicKey = secp256k1.secp256k1.Signature.fromCompact(sig.slice(0, 128)).addRecoveryBit(recoveryBit).recoverPublicKey(hashHex).toHex(false);
|
|
841
|
+
const recovered = accounts.publicKeyToAddress(`0x${publicKey}`);
|
|
842
|
+
return recovered.toLowerCase() === expectedAddress.toLowerCase();
|
|
843
|
+
} catch {
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
var TAX_DECLARATION_DOMAIN = { name: "x402 Tax Declaration", version: "1" };
|
|
848
|
+
var TAX_DECLARATION_PRIMARY_TYPE = "TaxDeclaration";
|
|
849
|
+
var TAX_DECLARATION_TYPES = {
|
|
850
|
+
TaxDeclaration: [
|
|
851
|
+
{ name: "version", type: "string" },
|
|
852
|
+
{ name: "jurisdiction", type: "string" },
|
|
853
|
+
{ name: "taxableStatus", type: "string" },
|
|
854
|
+
{ name: "taxId", type: "string" },
|
|
855
|
+
{ name: "validUntil", type: "uint256" },
|
|
856
|
+
{ name: "principalId", type: "string" },
|
|
857
|
+
{ name: "principalAttributionHash", type: "string" }
|
|
858
|
+
]
|
|
859
|
+
};
|
|
860
|
+
var X_TAX_DECLARATION_HEADER = "X-Tax-Declaration";
|
|
861
|
+
function validateContent(content) {
|
|
862
|
+
if (typeof content !== "object" || content === null || Array.isArray(content)) {
|
|
863
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError("Tax declaration content must be an object.");
|
|
864
|
+
}
|
|
865
|
+
const record = content;
|
|
866
|
+
for (const field of ["principalId", "principalAttributionHash"]) {
|
|
867
|
+
if (record[field] !== void 0) {
|
|
868
|
+
throw new TaxDeclarationRefusedError(
|
|
869
|
+
`Tax declaration content arrives with ${field} already set; that field is computed locally from the delegate key and the accepted payment option, never accepted from Haven.`
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
const allowed = /* @__PURE__ */ new Set(["version", "jurisdiction", "taxableStatus", "taxId", "validUntil"]);
|
|
874
|
+
for (const key of Object.keys(record)) {
|
|
875
|
+
if (!allowed.has(key)) {
|
|
876
|
+
throw new TaxDeclarationRefusedError(
|
|
877
|
+
`Tax declaration content carries an unknown field '${key}'; the signed shape is built locally from the \xA72.1 fields only.`
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
const strings = ["version", "jurisdiction", "taxableStatus", "taxId"];
|
|
882
|
+
for (const key of strings) {
|
|
883
|
+
if (typeof record[key] !== "string" || record[key].length === 0) {
|
|
884
|
+
throw new TaxDeclarationRefusedError(
|
|
885
|
+
`Tax declaration content field '${key}' must be a non-empty string.`
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
if (typeof record.validUntil !== "number" || !Number.isInteger(record.validUntil) || record.validUntil <= 0) {
|
|
890
|
+
throw new TaxDeclarationRefusedError(
|
|
891
|
+
"Tax declaration content field 'validUntil' must be a positive integer (milliseconds)."
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
return {
|
|
895
|
+
version: record.version,
|
|
896
|
+
jurisdiction: record.jurisdiction,
|
|
897
|
+
taxableStatus: record.taxableStatus,
|
|
898
|
+
taxId: record.taxId,
|
|
899
|
+
validUntil: record.validUntil
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
function jcsCanonicalBytes(value) {
|
|
903
|
+
const keys = Object.keys(value).sort();
|
|
904
|
+
const members = keys.map((key) => `${JSON.stringify(key)}:${JSON.stringify(value[key])}`);
|
|
905
|
+
return `{${members.join(",")}}`;
|
|
906
|
+
}
|
|
907
|
+
function principalAttributionHash(principalId) {
|
|
908
|
+
const canonical = jcsCanonicalBytes({ principalId });
|
|
909
|
+
const hex2 = crypto.createHash("sha256").update(canonical, "utf8").digest("hex");
|
|
910
|
+
return `sha-256:${hex2}`;
|
|
911
|
+
}
|
|
912
|
+
function taxPrincipalId(network, delegateAddress) {
|
|
913
|
+
if (network.startsWith("eip155:")) {
|
|
914
|
+
return `did:pkh:${network}:${delegateAddress}`;
|
|
915
|
+
}
|
|
916
|
+
const chainId = chunkHX34HOW4_cjs.chainIdForNetwork(network);
|
|
917
|
+
if (chainId === void 0) {
|
|
918
|
+
throw new TaxDeclarationRefusedError(
|
|
919
|
+
`The accepted payment option's network '${network}' is not a CAIP-2 eip155 chain this SDK can name; refusing to build a tax principal without the settlement network.`
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
return `did:pkh:eip155:${chainId}:${delegateAddress}`;
|
|
923
|
+
}
|
|
924
|
+
function buildSignedTaxDeclaration(input) {
|
|
925
|
+
const content = validateContent(input.content);
|
|
926
|
+
const principalId = taxPrincipalId(input.network, addressFromKeyForTax(input.delegateKey));
|
|
927
|
+
const attributionHash = principalAttributionHash(principalId);
|
|
928
|
+
const declaration = { ...content, principalId, principalAttributionHash: attributionHash };
|
|
929
|
+
const message = { ...declaration, validUntil: BigInt(declaration.validUntil) };
|
|
930
|
+
const digest = viem.hashTypedData({
|
|
931
|
+
domain: TAX_DECLARATION_DOMAIN,
|
|
932
|
+
types: TAX_DECLARATION_TYPES,
|
|
933
|
+
primaryType: TAX_DECLARATION_PRIMARY_TYPE,
|
|
934
|
+
message
|
|
935
|
+
});
|
|
936
|
+
const signature = signHash(input.delegateKey, digest);
|
|
937
|
+
return { declaration, signature };
|
|
938
|
+
}
|
|
939
|
+
function verifyTaxDeclarationSignature(declaration, signature, expectedAddress) {
|
|
940
|
+
const message = { ...declaration, validUntil: BigInt(declaration.validUntil) };
|
|
941
|
+
const digest = viem.hashTypedData({
|
|
942
|
+
domain: TAX_DECLARATION_DOMAIN,
|
|
943
|
+
types: TAX_DECLARATION_TYPES,
|
|
944
|
+
primaryType: TAX_DECLARATION_PRIMARY_TYPE,
|
|
945
|
+
message
|
|
946
|
+
});
|
|
947
|
+
return verifySignature(digest, signature, expectedAddress);
|
|
948
|
+
}
|
|
949
|
+
function encodeTaxDeclarationHeader(result) {
|
|
950
|
+
const json = JSON.stringify({ ...result.declaration, signature: result.signature });
|
|
951
|
+
return base64Url(json);
|
|
952
|
+
}
|
|
953
|
+
function base64Url(value) {
|
|
954
|
+
const standard = typeof Buffer !== "undefined" ? Buffer.from(value, "utf8").toString("base64") : btoa(String.fromCharCode(...new TextEncoder().encode(value)));
|
|
955
|
+
return standard.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
956
|
+
}
|
|
957
|
+
function addressFromKeyForTax(delegateKey) {
|
|
958
|
+
try {
|
|
959
|
+
return addressFromKey(delegateKey);
|
|
960
|
+
} catch (err) {
|
|
961
|
+
throw new chunkHX34HOW4_cjs.HavenSigningError(
|
|
962
|
+
`Invalid delegate key for tax declaration signing: ${err instanceof Error ? err.message : String(err)}`
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
var TaxDeclarationRefusedError = class extends chunkHX34HOW4_cjs.HavenSigningError {
|
|
967
|
+
code = "TAX_DECLARATION_REFUSED";
|
|
968
|
+
constructor(message) {
|
|
969
|
+
super(message);
|
|
970
|
+
this.name = "TaxDeclarationRefusedError";
|
|
971
|
+
}
|
|
972
|
+
};
|
|
804
973
|
|
|
805
974
|
// src/next-step.ts
|
|
806
975
|
var NEXT_TOOL_SERVER_NAMES = {
|
|
@@ -946,10 +1115,10 @@ function assertOwnTaskChild(typedData, expected, delegateAddress, now = Date.now
|
|
|
946
1115
|
if (td?.primaryType !== "Delegation") {
|
|
947
1116
|
refuseTaskChild("it is not a Delegation payload", `primaryType was '${String(td?.primaryType)}'.`);
|
|
948
1117
|
}
|
|
949
|
-
if (!same(td.domain?.verifyingContract,
|
|
1118
|
+
if (!same(td.domain?.verifyingContract, chunkHX34HOW4_cjs.DELEGATION_MANAGER)) {
|
|
950
1119
|
refuseTaskChild(
|
|
951
1120
|
"the EIP-712 domain names an unknown DelegationManager",
|
|
952
|
-
`Expected ${
|
|
1121
|
+
`Expected ${chunkHX34HOW4_cjs.DELEGATION_MANAGER}, got ${td.domain?.verifyingContract}.`
|
|
953
1122
|
);
|
|
954
1123
|
}
|
|
955
1124
|
if (td.domain?.name !== DELEGATION_DOMAIN_NAME || td.domain?.version !== DELEGATION_DOMAIN_VERSION) {
|
|
@@ -977,7 +1146,7 @@ function assertOwnTaskChild(typedData, expected, delegateAddress, now = Date.now
|
|
|
977
1146
|
`Expected chain ${expected.chainId}; the child says ${td.domain?.chainId}.`
|
|
978
1147
|
);
|
|
979
1148
|
}
|
|
980
|
-
const ownAccount =
|
|
1149
|
+
const ownAccount = chunkHX34HOW4_cjs.deriveDelegateAccountAddress(delegateAddress);
|
|
981
1150
|
const delegator = td.message?.delegator;
|
|
982
1151
|
if (typeof delegator !== "string" || !same(delegator, ownAccount)) {
|
|
983
1152
|
refuseTaskChild(
|
|
@@ -996,7 +1165,7 @@ function assertOwnTaskChild(typedData, expected, delegateAddress, now = Date.now
|
|
|
996
1165
|
if (typeof authority !== "string" || !/^0x[0-9a-fA-F]{64}$/.test(authority)) {
|
|
997
1166
|
refuseTaskChild("its authority is not a 32-byte delegation hash", `Got ${String(authority)}.`);
|
|
998
1167
|
}
|
|
999
|
-
if (authority.toLowerCase() ===
|
|
1168
|
+
if (authority.toLowerCase() === chunkHX34HOW4_cjs.ROOT_AUTHORITY) {
|
|
1000
1169
|
refuseTaskChild(
|
|
1001
1170
|
"it is a ROOT delegation, not a re-delegation of the agent budget",
|
|
1002
1171
|
"A task budget always chains under the agent budget delegation."
|
|
@@ -1009,7 +1178,7 @@ function assertOwnTaskChild(typedData, expected, delegateAddress, now = Date.now
|
|
|
1009
1178
|
);
|
|
1010
1179
|
}
|
|
1011
1180
|
const caveats = td.message?.caveats ?? [];
|
|
1012
|
-
const transfer = findCaveat(caveats,
|
|
1181
|
+
const transfer = findCaveat(caveats, chunkHX34HOW4_cjs.CAVEAT_ENFORCERS.erc20TransferAmount);
|
|
1013
1182
|
if (!transfer) {
|
|
1014
1183
|
refuseTaskChild(
|
|
1015
1184
|
"it has no ERC-20 transfer-amount caveat",
|
|
@@ -1027,7 +1196,7 @@ function assertOwnTaskChild(typedData, expected, delegateAddress, now = Date.now
|
|
|
1027
1196
|
`Expected ${expected.maxAmountAtomic}; the child allows ${amount.toString()}.`
|
|
1028
1197
|
);
|
|
1029
1198
|
}
|
|
1030
|
-
const timestamp = findCaveat(caveats,
|
|
1199
|
+
const timestamp = findCaveat(caveats, chunkHX34HOW4_cjs.CAVEAT_ENFORCERS.timestamp);
|
|
1031
1200
|
if (!timestamp) {
|
|
1032
1201
|
refuseTaskChild("it never expires", "A task-budget child without a timestamp caveat is open-ended.");
|
|
1033
1202
|
}
|
|
@@ -1048,7 +1217,7 @@ function assertOwnTaskChild(typedData, expected, delegateAddress, now = Date.now
|
|
|
1048
1217
|
`Expected ${expected.expiresAt}; the child says ${beforeThreshold}.`
|
|
1049
1218
|
);
|
|
1050
1219
|
}
|
|
1051
|
-
const calldata = findCaveat(caveats,
|
|
1220
|
+
const calldata = findCaveat(caveats, chunkHX34HOW4_cjs.CAVEAT_ENFORCERS.allowedCalldata);
|
|
1052
1221
|
if (expected.recipientAddress) {
|
|
1053
1222
|
if (!calldata) {
|
|
1054
1223
|
refuseTaskChild(
|
|
@@ -1085,7 +1254,7 @@ var DISABLE_DELEGATION_ABI = [
|
|
|
1085
1254
|
{
|
|
1086
1255
|
type: "function",
|
|
1087
1256
|
name: "disableDelegation",
|
|
1088
|
-
inputs: [{ name: "delegation", type: "tuple", components:
|
|
1257
|
+
inputs: [{ name: "delegation", type: "tuple", components: chunkHX34HOW4_cjs.DELEGATION_TUPLE_COMPONENTS }],
|
|
1089
1258
|
outputs: [],
|
|
1090
1259
|
stateMutability: "nonpayable"
|
|
1091
1260
|
}
|
|
@@ -1104,7 +1273,7 @@ function assertOwnTaskBudgetCloseUserOp(typedData, expected, delegateAddress) {
|
|
|
1104
1273
|
`This signer only signs a task-budget close on chains the delegation rail has pinned contracts for (${[...DIRECT_PAYMENT_CHAIN_IDS].join(", ")}); this typed data names chain ${String(domain.chainId)}. Refusing.`
|
|
1105
1274
|
);
|
|
1106
1275
|
}
|
|
1107
|
-
const ownAccount =
|
|
1276
|
+
const ownAccount = chunkHX34HOW4_cjs.deriveDelegateAccountAddress(delegateAddress);
|
|
1108
1277
|
const sender = typeof message.sender === "string" ? message.sender : "";
|
|
1109
1278
|
if (sender.toLowerCase() !== ownAccount.toLowerCase()) {
|
|
1110
1279
|
throw new HavenTypedDataRefusedError(
|
|
@@ -1127,9 +1296,9 @@ function assertOwnTaskBudgetCloseUserOp(typedData, expected, delegateAddress) {
|
|
|
1127
1296
|
"This close UserOperation's execute() call does not re-encode to the exact callData bytes (trailing or non-canonical bytes). Refusing."
|
|
1128
1297
|
);
|
|
1129
1298
|
}
|
|
1130
|
-
if (decoded.target.toLowerCase() !==
|
|
1299
|
+
if (decoded.target.toLowerCase() !== chunkHX34HOW4_cjs.DELEGATION_MANAGER.toLowerCase()) {
|
|
1131
1300
|
throw new HavenTypedDataRefusedError(
|
|
1132
|
-
`This close UserOperation's execute() calls ${decoded.target}, not the DelegationManager (${
|
|
1301
|
+
`This close UserOperation's execute() calls ${decoded.target}, not the DelegationManager (${chunkHX34HOW4_cjs.DELEGATION_MANAGER}). Refusing what looks like a self-call or a call to an unrelated contract.`
|
|
1133
1302
|
);
|
|
1134
1303
|
}
|
|
1135
1304
|
if (decoded.value !== 0n) {
|
|
@@ -1166,7 +1335,7 @@ function assertOwnTaskBudgetCloseUserOp(typedData, expected, delegateAddress) {
|
|
|
1166
1335
|
`This close UserOperation disables a delegation granted to ${delegation.delegate}, not this signer's own account (${ownAccount}) \u2014 a task-budget child is always self-delegated. Refusing.`
|
|
1167
1336
|
);
|
|
1168
1337
|
}
|
|
1169
|
-
if (delegation.authority.toLowerCase() ===
|
|
1338
|
+
if (delegation.authority.toLowerCase() === chunkHX34HOW4_cjs.ROOT_AUTHORITY) {
|
|
1170
1339
|
throw new HavenTypedDataRefusedError(
|
|
1171
1340
|
"This close UserOperation disables a ROOT delegation, not a re-delegation of the agent budget. A task-budget child always chains under the agent budget delegation. Refusing."
|
|
1172
1341
|
);
|
|
@@ -1226,8 +1395,12 @@ exports.SWEEP_BASE_CHAIN_ID = SWEEP_BASE_CHAIN_ID;
|
|
|
1226
1395
|
exports.SWEEP_BASE_SEPOLIA_CHAIN_ID = SWEEP_BASE_SEPOLIA_CHAIN_ID;
|
|
1227
1396
|
exports.SWEEP_BASE_SEPOLIA_USDC_ADDRESS = SWEEP_BASE_SEPOLIA_USDC_ADDRESS;
|
|
1228
1397
|
exports.SWEEP_BASE_USDC_ADDRESS = SWEEP_BASE_USDC_ADDRESS;
|
|
1398
|
+
exports.TAX_DECLARATION_DOMAIN = TAX_DECLARATION_DOMAIN;
|
|
1399
|
+
exports.TAX_DECLARATION_PRIMARY_TYPE = TAX_DECLARATION_PRIMARY_TYPE;
|
|
1400
|
+
exports.TAX_DECLARATION_TYPES = TAX_DECLARATION_TYPES;
|
|
1229
1401
|
exports.TRANSFER_WITH_AUTHORIZATION_TYPES = TRANSFER_WITH_AUTHORIZATION_TYPES;
|
|
1230
1402
|
exports.TYPED_DATA_NOT_ALLOWED = TYPED_DATA_NOT_ALLOWED;
|
|
1403
|
+
exports.TaxDeclarationRefusedError = TaxDeclarationRefusedError;
|
|
1231
1404
|
exports.X402PaymentHeaderValidationError = X402PaymentHeaderValidationError;
|
|
1232
1405
|
exports.X402_LEGACY_PAYMENT_HEADER_NAME = X402_LEGACY_PAYMENT_HEADER_NAME;
|
|
1233
1406
|
exports.X402_MAX_AUTHORIZATION_WINDOW_SECONDS = X402_MAX_AUTHORIZATION_WINDOW_SECONDS;
|
|
@@ -1237,11 +1410,14 @@ exports.X402_PAYMENT_HEADER_NAMES_SENT = X402_PAYMENT_HEADER_NAMES_SENT;
|
|
|
1237
1410
|
exports.X402_PAYMENT_REQUIRED_HEADER_NAME = X402_PAYMENT_REQUIRED_HEADER_NAME;
|
|
1238
1411
|
exports.X402_PAYMENT_RESPONSE_HEADER_NAME = X402_PAYMENT_RESPONSE_HEADER_NAME;
|
|
1239
1412
|
exports.X402_SETTLEMENT_FORWARD_MARGIN_SECONDS = X402_SETTLEMENT_FORWARD_MARGIN_SECONDS;
|
|
1413
|
+
exports.X_TAX_DECLARATION_HEADER = X_TAX_DECLARATION_HEADER;
|
|
1414
|
+
exports.addressFromKey = addressFromKey;
|
|
1240
1415
|
exports.assertBoundDirectPaymentUserOp = assertBoundDirectPaymentUserOp;
|
|
1241
1416
|
exports.assertFundingLegPaysDelegate = assertFundingLegPaysDelegate;
|
|
1242
1417
|
exports.assertOwnSettlementChild = assertOwnSettlementChild;
|
|
1243
1418
|
exports.assertOwnTaskBudgetCloseUserOp = assertOwnTaskBudgetCloseUserOp;
|
|
1244
1419
|
exports.assertOwnTaskChild = assertOwnTaskChild;
|
|
1420
|
+
exports.buildSignedTaxDeclaration = buildSignedTaxDeclaration;
|
|
1245
1421
|
exports.buildSweepAuthorizationMessage = buildSweepAuthorizationMessage;
|
|
1246
1422
|
exports.buildSweepTypedData = buildSweepTypedData;
|
|
1247
1423
|
exports.buildX402ExpectedMessage = buildX402ExpectedMessage;
|
|
@@ -1254,6 +1430,7 @@ exports.defaultNextToolFor = defaultNextToolFor;
|
|
|
1254
1430
|
exports.encodeBase64Json = encodeBase64Json;
|
|
1255
1431
|
exports.encodeBase64Utf8 = encodeBase64Utf8;
|
|
1256
1432
|
exports.encodePaymentProof = encodePaymentProof;
|
|
1433
|
+
exports.encodeTaxDeclarationHeader = encodeTaxDeclarationHeader;
|
|
1257
1434
|
exports.hashDelegation = hashDelegation;
|
|
1258
1435
|
exports.havenClientIdentity = havenClientIdentity;
|
|
1259
1436
|
exports.isErc7710Option = isErc7710Option;
|
|
@@ -1264,23 +1441,29 @@ exports.normalizePaymentRequired = normalizePaymentRequired;
|
|
|
1264
1441
|
exports.parseNextTool = parseNextTool;
|
|
1265
1442
|
exports.parsePaymentRequired = parsePaymentRequired;
|
|
1266
1443
|
exports.parsePaymentRequiredResponse = parsePaymentRequiredResponse;
|
|
1444
|
+
exports.principalAttributionHash = principalAttributionHash;
|
|
1267
1445
|
exports.readClientUpdate = readClientUpdate;
|
|
1268
1446
|
exports.renderNextTool = renderNextTool;
|
|
1447
|
+
exports.resolveTokenBySymbol = resolveTokenBySymbol;
|
|
1269
1448
|
exports.resolveTokenFromAddress = resolveTokenFromAddress;
|
|
1270
1449
|
exports.selectErc7710PaymentOption = selectErc7710PaymentOption;
|
|
1271
1450
|
exports.selectPaymentOption = selectPaymentOption;
|
|
1272
1451
|
exports.selectStandardPaymentOption = selectStandardPaymentOption;
|
|
1273
1452
|
exports.selectX402SettlementScheme = selectX402SettlementScheme;
|
|
1453
|
+
exports.signHash = signHash;
|
|
1274
1454
|
exports.sweepUsdcAddress = sweepUsdcAddress;
|
|
1275
1455
|
exports.sweepUsdcDomain = sweepUsdcDomain;
|
|
1456
|
+
exports.taxPrincipalId = taxPrincipalId;
|
|
1276
1457
|
exports.toStandardPaymentRequirements = toStandardPaymentRequirements;
|
|
1277
1458
|
exports.unsupportedNodeVersionMessage = unsupportedNodeVersionMessage;
|
|
1278
1459
|
exports.validateStandardX402PaymentHeader = validateStandardX402PaymentHeader;
|
|
1460
|
+
exports.verifySignature = verifySignature;
|
|
1461
|
+
exports.verifyTaxDeclarationSignature = verifyTaxDeclarationSignature;
|
|
1279
1462
|
exports.x402AssetTransferMethod = x402AssetTransferMethod;
|
|
1280
1463
|
exports.x402AuthorizationAmount = x402AuthorizationAmount;
|
|
1281
1464
|
exports.x402FacilitatorAddresses = x402FacilitatorAddresses;
|
|
1282
1465
|
exports.x402PaymentHeaderNamesFor = x402PaymentHeaderNamesFor;
|
|
1283
1466
|
exports.x402PaymentHeaderNamesSent = x402PaymentHeaderNamesSent;
|
|
1284
1467
|
exports.x402V2PaymentEnvelope = x402V2PaymentEnvelope;
|
|
1285
|
-
//# sourceMappingURL=chunk-
|
|
1286
|
-
//# sourceMappingURL=chunk-
|
|
1468
|
+
//# sourceMappingURL=chunk-WJFDXCYP.cjs.map
|
|
1469
|
+
//# sourceMappingURL=chunk-WJFDXCYP.cjs.map
|