@hyperlane-xyz/sdk 32.0.1 → 33.0.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/consts/testChains.d.ts +2 -2
- package/dist/consts/testChains.d.ts.map +1 -1
- package/dist/consts/testChains.js +21 -21
- package/dist/consts/testChains.js.map +1 -1
- package/dist/core/EvmCoreModule.d.ts.map +1 -1
- package/dist/core/EvmCoreModule.js +2 -1
- package/dist/core/EvmCoreModule.js.map +1 -1
- package/dist/core/HyperlaneCoreDeployer.d.ts.map +1 -1
- package/dist/core/HyperlaneCoreDeployer.js +1 -0
- package/dist/core/HyperlaneCoreDeployer.js.map +1 -1
- package/dist/core/types.d.ts +124 -22
- package/dist/core/types.d.ts.map +1 -1
- package/dist/deploy/warp.d.ts.map +1 -1
- package/dist/deploy/warp.js +3 -1
- package/dist/deploy/warp.js.map +1 -1
- package/dist/hook/EvmHookReader.d.ts.map +1 -1
- package/dist/hook/EvmHookReader.js +4 -0
- package/dist/hook/EvmHookReader.js.map +1 -1
- package/dist/hook/HyperlaneHookDeployer.d.ts.map +1 -1
- package/dist/hook/HyperlaneHookDeployer.js +19 -10
- package/dist/hook/HyperlaneHookDeployer.js.map +1 -1
- package/dist/hook/types.d.ts +118 -17
- package/dist/hook/types.d.ts.map +1 -1
- package/dist/hook/types.js +14 -0
- package/dist/hook/types.js.map +1 -1
- package/dist/hook/updates.d.ts +4 -1
- package/dist/hook/updates.d.ts.map +1 -1
- package/dist/hook/updates.js +1 -1
- package/dist/hook/updates.js.map +1 -1
- package/dist/hook/utils.d.ts +7 -1
- package/dist/hook/utils.d.ts.map +1 -1
- package/dist/hook/utils.js +18 -0
- package/dist/hook/utils.js.map +1 -1
- package/dist/ica/types.d.ts +36 -6
- package/dist/ica/types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/metadata/ChainMetadataResolver.d.ts.map +1 -1
- package/dist/metadata/ChainMetadataResolver.js +1 -13
- package/dist/metadata/ChainMetadataResolver.js.map +1 -1
- package/dist/metadata/chainIdUtils.d.ts +8 -0
- package/dist/metadata/chainIdUtils.d.ts.map +1 -0
- package/dist/metadata/chainIdUtils.js +33 -0
- package/dist/metadata/chainIdUtils.js.map +1 -0
- package/dist/metadata/chainIdUtils.test.d.ts +2 -0
- package/dist/metadata/chainIdUtils.test.d.ts.map +1 -0
- package/dist/metadata/chainIdUtils.test.js +45 -0
- package/dist/metadata/chainIdUtils.test.js.map +1 -0
- package/dist/predicate/PredicateApiClient.d.ts +45 -0
- package/dist/predicate/PredicateApiClient.d.ts.map +1 -0
- package/dist/predicate/PredicateApiClient.js +66 -0
- package/dist/predicate/PredicateApiClient.js.map +1 -0
- package/dist/predicate/PredicateApiClient.test.d.ts +2 -0
- package/dist/predicate/PredicateApiClient.test.d.ts.map +1 -0
- package/dist/predicate/PredicateApiClient.test.js +108 -0
- package/dist/predicate/PredicateApiClient.test.js.map +1 -0
- package/dist/predicate/PredicateDeployer.d.ts +56 -0
- package/dist/predicate/PredicateDeployer.d.ts.map +1 -0
- package/dist/predicate/PredicateDeployer.hardhat-test.d.ts +2 -0
- package/dist/predicate/PredicateDeployer.hardhat-test.d.ts.map +1 -0
- package/dist/predicate/PredicateDeployer.hardhat-test.js +209 -0
- package/dist/predicate/PredicateDeployer.hardhat-test.js.map +1 -0
- package/dist/predicate/PredicateDeployer.js +218 -0
- package/dist/predicate/PredicateDeployer.js.map +1 -0
- package/dist/router/types.d.ts +54 -9
- package/dist/router/types.d.ts.map +1 -1
- package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.js +6 -6
- package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.js.map +1 -1
- package/dist/test/testUtils.d.ts +1 -1
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +1 -0
- package/dist/test/testUtils.js.map +1 -1
- package/dist/timelock/evm/EvmTimelockReader.hardhat-test.js +4 -4
- package/dist/timelock/evm/EvmTimelockReader.hardhat-test.js.map +1 -1
- package/dist/token/EvmWarpModule.d.ts +55 -0
- package/dist/token/EvmWarpModule.d.ts.map +1 -1
- package/dist/token/EvmWarpModule.hardhat-test.js +29 -0
- package/dist/token/EvmWarpModule.hardhat-test.js.map +1 -1
- package/dist/token/EvmWarpModule.js +264 -21
- package/dist/token/EvmWarpModule.js.map +1 -1
- package/dist/token/EvmWarpRouteReader.d.ts +6 -0
- package/dist/token/EvmWarpRouteReader.d.ts.map +1 -1
- package/dist/token/EvmWarpRouteReader.js +34 -1
- package/dist/token/EvmWarpRouteReader.js.map +1 -1
- package/dist/token/TokenMetadata.d.ts.map +1 -1
- package/dist/token/TokenMetadata.js +2 -3
- package/dist/token/TokenMetadata.js.map +1 -1
- package/dist/token/adapters/EvmCrossCollateralAdapter.d.ts +2 -8
- package/dist/token/adapters/EvmCrossCollateralAdapter.d.ts.map +1 -1
- package/dist/token/adapters/EvmCrossCollateralAdapter.js +23 -4
- package/dist/token/adapters/EvmCrossCollateralAdapter.js.map +1 -1
- package/dist/token/adapters/EvmTokenAdapter.d.ts +21 -4
- package/dist/token/adapters/EvmTokenAdapter.d.ts.map +1 -1
- package/dist/token/adapters/EvmTokenAdapter.js +191 -22
- package/dist/token/adapters/EvmTokenAdapter.js.map +1 -1
- package/dist/token/adapters/ITokenAdapter.d.ts +10 -0
- package/dist/token/adapters/ITokenAdapter.d.ts.map +1 -1
- package/dist/token/adapters/ITokenAdapter.js +8 -0
- package/dist/token/adapters/ITokenAdapter.js.map +1 -1
- package/dist/token/deploy.d.ts +4 -1
- package/dist/token/deploy.d.ts.map +1 -1
- package/dist/token/deploy.js +30 -1
- package/dist/token/deploy.js.map +1 -1
- package/dist/token/types.d.ts +4427 -27
- package/dist/token/types.d.ts.map +1 -1
- package/dist/token/types.js +19 -0
- package/dist/token/types.js.map +1 -1
- package/dist/warp/WarpCore.d.ts +39 -19
- package/dist/warp/WarpCore.d.ts.map +1 -1
- package/dist/warp/WarpCore.js +149 -82
- package/dist/warp/WarpCore.js.map +1 -1
- package/dist/warp/WarpCore.test.js +58 -0
- package/dist/warp/WarpCore.test.js.map +1 -1
- package/package.json +10 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chainIdUtils.test.d.ts","sourceRoot":"","sources":["../../src/metadata/chainIdUtils.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { areChainIdsEqual, getEffectiveDomainId, tryNormalizeNumericChainId, } from './chainIdUtils.js';
|
|
3
|
+
describe(tryNormalizeNumericChainId.name, () => {
|
|
4
|
+
it('accepts safe integer numbers', () => {
|
|
5
|
+
expect(tryNormalizeNumericChainId(0)).to.equal(0);
|
|
6
|
+
expect(tryNormalizeNumericChainId(123)).to.equal(123);
|
|
7
|
+
});
|
|
8
|
+
it('accepts canonical numeric strings', () => {
|
|
9
|
+
expect(tryNormalizeNumericChainId('0')).to.equal(0);
|
|
10
|
+
expect(tryNormalizeNumericChainId('123')).to.equal(123);
|
|
11
|
+
});
|
|
12
|
+
it('rejects non-canonical or invalid inputs', () => {
|
|
13
|
+
expect(tryNormalizeNumericChainId('00123')).to.equal(null);
|
|
14
|
+
expect(tryNormalizeNumericChainId('cosmoshub-4')).to.equal(null);
|
|
15
|
+
expect(tryNormalizeNumericChainId(1.5)).to.equal(null);
|
|
16
|
+
expect(tryNormalizeNumericChainId(Number.MAX_SAFE_INTEGER + 1)).to.equal(null);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
describe(areChainIdsEqual.name, () => {
|
|
20
|
+
it('matches exact values and canonical numeric aliases', () => {
|
|
21
|
+
expect(areChainIdsEqual(123, 123)).to.equal(true);
|
|
22
|
+
expect(areChainIdsEqual('123', 123)).to.equal(true);
|
|
23
|
+
});
|
|
24
|
+
it('rejects nullish and non-matching values', () => {
|
|
25
|
+
expect(areChainIdsEqual(undefined, 123)).to.equal(false);
|
|
26
|
+
expect(areChainIdsEqual(null, '123')).to.equal(false);
|
|
27
|
+
expect(areChainIdsEqual(5, 10)).to.equal(false);
|
|
28
|
+
expect(areChainIdsEqual('5', 10)).to.equal(false);
|
|
29
|
+
expect(areChainIdsEqual('00123', 123)).to.equal(false);
|
|
30
|
+
expect(areChainIdsEqual('cosmoshub-4', 4)).to.equal(false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe(getEffectiveDomainId.name, () => {
|
|
34
|
+
it('prefers explicit domain ids', () => {
|
|
35
|
+
expect(getEffectiveDomainId({ chainId: 1, domainId: 999 })).to.equal(999);
|
|
36
|
+
});
|
|
37
|
+
it('falls back to normalized chain ids when domain id is absent', () => {
|
|
38
|
+
expect(getEffectiveDomainId({ chainId: 123 })).to.equal(123);
|
|
39
|
+
expect(getEffectiveDomainId({ chainId: '123' })).to.equal(123);
|
|
40
|
+
});
|
|
41
|
+
it('returns null for non-numeric fallback chain ids', () => {
|
|
42
|
+
expect(getEffectiveDomainId({ chainId: 'cosmoshub-4' })).to.equal(null);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=chainIdUtils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chainIdUtils.test.js","sourceRoot":"","sources":["../../src/metadata/chainIdUtils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export interface PredicateAttestation {
|
|
3
|
+
uuid: string;
|
|
4
|
+
expiration: number;
|
|
5
|
+
attester: string;
|
|
6
|
+
signature: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PredicateAttestationResponse {
|
|
9
|
+
policy_id: string;
|
|
10
|
+
policy_name: string;
|
|
11
|
+
verification_hash: string;
|
|
12
|
+
is_compliant: boolean;
|
|
13
|
+
attestation: PredicateAttestation;
|
|
14
|
+
}
|
|
15
|
+
export interface PredicateAttestationRequest {
|
|
16
|
+
to: string;
|
|
17
|
+
from: string;
|
|
18
|
+
data: string;
|
|
19
|
+
msg_value: string;
|
|
20
|
+
chain: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const PredicateAttestationSchema: z.ZodObject<{
|
|
23
|
+
uuid: z.ZodString;
|
|
24
|
+
expiration: z.ZodNumber;
|
|
25
|
+
attester: z.ZodString;
|
|
26
|
+
signature: z.ZodString;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
signature: string;
|
|
29
|
+
expiration: number;
|
|
30
|
+
uuid: string;
|
|
31
|
+
attester: string;
|
|
32
|
+
}, {
|
|
33
|
+
signature: string;
|
|
34
|
+
expiration: number;
|
|
35
|
+
uuid: string;
|
|
36
|
+
attester: string;
|
|
37
|
+
}>;
|
|
38
|
+
export declare class PredicateApiClient {
|
|
39
|
+
private readonly logger;
|
|
40
|
+
private readonly baseUrl;
|
|
41
|
+
private readonly apiKey;
|
|
42
|
+
constructor(apiKey: string, baseUrl?: string);
|
|
43
|
+
fetchAttestation(request: PredicateAttestationRequest): Promise<PredicateAttestationResponse>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=PredicateApiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateApiClient.d.ts","sourceRoot":"","sources":["../../src/predicate/PredicateApiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;EAKrC,CAAC;AAUH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsD;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAkC;IAMjE,gBAAgB,CACpB,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,4BAA4B,CAAC;CAkDzC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { assert, rootLogger } from '@hyperlane-xyz/utils';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
const DEFAULT_PREDICATE_API_URL = 'https://api.predicate.io/v2/attestation';
|
|
4
|
+
export const PredicateAttestationSchema = z.object({
|
|
5
|
+
uuid: z.string(),
|
|
6
|
+
expiration: z.number(),
|
|
7
|
+
attester: z.string(),
|
|
8
|
+
signature: z.string(),
|
|
9
|
+
});
|
|
10
|
+
const PredicateAttestationResponseSchema = z.object({
|
|
11
|
+
policy_id: z.string(),
|
|
12
|
+
policy_name: z.string(),
|
|
13
|
+
verification_hash: z.string(),
|
|
14
|
+
is_compliant: z.boolean(),
|
|
15
|
+
attestation: PredicateAttestationSchema,
|
|
16
|
+
});
|
|
17
|
+
export class PredicateApiClient {
|
|
18
|
+
logger = rootLogger.child({ module: 'PredicateApiClient' });
|
|
19
|
+
baseUrl;
|
|
20
|
+
apiKey;
|
|
21
|
+
constructor(apiKey, baseUrl = DEFAULT_PREDICATE_API_URL) {
|
|
22
|
+
assert(apiKey, 'Predicate API key is required');
|
|
23
|
+
this.apiKey = apiKey;
|
|
24
|
+
this.baseUrl = baseUrl;
|
|
25
|
+
}
|
|
26
|
+
async fetchAttestation(request) {
|
|
27
|
+
this.logger.debug('Fetching attestation', {
|
|
28
|
+
url: this.baseUrl,
|
|
29
|
+
request,
|
|
30
|
+
});
|
|
31
|
+
const controller = new AbortController();
|
|
32
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
33
|
+
let response;
|
|
34
|
+
try {
|
|
35
|
+
response = await fetch(this.baseUrl, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
'x-api-key': this.apiKey,
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify(request),
|
|
42
|
+
signal: controller.signal,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
clearTimeout(timeoutId);
|
|
47
|
+
}
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
const errorText = await response.text();
|
|
50
|
+
throw new Error(`Predicate API error (${response.status}): ${errorText}`);
|
|
51
|
+
}
|
|
52
|
+
const result = PredicateAttestationResponseSchema.parse(await response.json());
|
|
53
|
+
if (!result.is_compliant) {
|
|
54
|
+
throw new Error(`Transaction not compliant: policy=${result.policy_id}, hash=${result.verification_hash}`);
|
|
55
|
+
}
|
|
56
|
+
const now = Math.floor(Date.now() / 1000);
|
|
57
|
+
if (result.attestation.expiration <= now) {
|
|
58
|
+
throw new Error(`Attestation already expired (expiration=${result.attestation.expiration}, now=${now})`);
|
|
59
|
+
}
|
|
60
|
+
this.logger.debug('Attestation received', {
|
|
61
|
+
uuid: result.attestation.uuid,
|
|
62
|
+
});
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=PredicateApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateApiClient.js","sourceRoot":"","sources":["../../src/predicate/PredicateApiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,yBAAyB,GAAG,yCAAyC,CAAC;AAyB5E,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAEH,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC7B,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE;IACzB,WAAW,EAAE,0BAA0B;CACxC,CAAC,CAAC;AAEH,MAAM,OAAO,kBAAkB;IACZ,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAS;IAChB,MAAM,CAAS;IAEhC,YAAY,MAAc,EAAE,UAAkB,yBAAyB;QACrE,MAAM,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,OAAoC;QAEpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;YACxC,GAAG,EAAE,IAAI,CAAC,OAAO;YACjB,OAAO;SACR,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/D,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE;gBACnC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,WAAW,EAAE,IAAI,CAAC,MAAM;iBACzB;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,MAAM,GAAG,kCAAkC,CAAC,KAAK,CACrD,MAAM,QAAQ,CAAC,IAAI,EAAE,CACtB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,qCAAqC,MAAM,CAAC,SAAS,UAAU,MAAM,CAAC,iBAAiB,EAAE,CAC1F,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,WAAW,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,2CAA2C,MAAM,CAAC,WAAW,CAAC,UAAU,SAAS,GAAG,GAAG,CACxF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;YACxC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;SAC9B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateApiClient.test.d.ts","sourceRoot":"","sources":["../../src/predicate/PredicateApiClient.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
import { PredicateApiClient, } from './PredicateApiClient.js';
|
|
4
|
+
describe('PredicateApiClient', () => {
|
|
5
|
+
let fetchStub;
|
|
6
|
+
const mockRequest = {
|
|
7
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
8
|
+
from: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd',
|
|
9
|
+
data: '0x',
|
|
10
|
+
msg_value: '0',
|
|
11
|
+
chain: 'sepolia',
|
|
12
|
+
};
|
|
13
|
+
const mockResponse = {
|
|
14
|
+
policy_id: 'policy_abc123',
|
|
15
|
+
policy_name: 'Test Policy',
|
|
16
|
+
verification_hash: 'x-test-hash',
|
|
17
|
+
is_compliant: true,
|
|
18
|
+
attestation: {
|
|
19
|
+
uuid: '550e8400-e29b-41d4-a716-446655440000',
|
|
20
|
+
expiration: Math.floor(Date.now() / 1000) + 3600,
|
|
21
|
+
attester: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
22
|
+
signature: '0x1234abcd',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
fetchStub = sinon.stub(global, 'fetch');
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
fetchStub.restore();
|
|
30
|
+
});
|
|
31
|
+
it('should fetch attestation successfully', async () => {
|
|
32
|
+
fetchStub.resolves({
|
|
33
|
+
ok: true,
|
|
34
|
+
json: async () => mockResponse,
|
|
35
|
+
});
|
|
36
|
+
const client = new PredicateApiClient('test-api-key');
|
|
37
|
+
const result = await client.fetchAttestation(mockRequest);
|
|
38
|
+
expect(result.is_compliant).to.be.true;
|
|
39
|
+
expect(result.attestation.uuid).to.equal(mockResponse.attestation.uuid);
|
|
40
|
+
expect(fetchStub.calledOnce).to.be.true;
|
|
41
|
+
});
|
|
42
|
+
it('should throw on non-compliant response', async () => {
|
|
43
|
+
fetchStub.resolves({
|
|
44
|
+
ok: true,
|
|
45
|
+
json: async () => ({ ...mockResponse, is_compliant: false }),
|
|
46
|
+
});
|
|
47
|
+
const client = new PredicateApiClient('test-api-key');
|
|
48
|
+
try {
|
|
49
|
+
await client.fetchAttestation(mockRequest);
|
|
50
|
+
expect.fail('Expected error to be thrown');
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
expect(error.message).to.include('Transaction not compliant');
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
it('should throw on API error', async () => {
|
|
57
|
+
fetchStub.resolves({
|
|
58
|
+
ok: false,
|
|
59
|
+
status: 401,
|
|
60
|
+
text: async () => 'Unauthorized',
|
|
61
|
+
});
|
|
62
|
+
const client = new PredicateApiClient('test-api-key');
|
|
63
|
+
try {
|
|
64
|
+
await client.fetchAttestation(mockRequest);
|
|
65
|
+
expect.fail('Expected error to be thrown');
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
expect(error.message).to.include('Predicate API error (401)');
|
|
69
|
+
expect(error.message).to.include('Unauthorized');
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
it('should use custom base URL', async () => {
|
|
73
|
+
fetchStub.resolves({
|
|
74
|
+
ok: true,
|
|
75
|
+
json: async () => mockResponse,
|
|
76
|
+
});
|
|
77
|
+
const customUrl = 'https://custom.predicate.io/v2/attestation';
|
|
78
|
+
const client = new PredicateApiClient('test-api-key', customUrl);
|
|
79
|
+
await client.fetchAttestation(mockRequest);
|
|
80
|
+
expect(fetchStub.firstCall.args[0]).to.equal(customUrl);
|
|
81
|
+
});
|
|
82
|
+
it('should include API key in headers', async () => {
|
|
83
|
+
fetchStub.resolves({
|
|
84
|
+
ok: true,
|
|
85
|
+
json: async () => mockResponse,
|
|
86
|
+
});
|
|
87
|
+
const client = new PredicateApiClient('my-secret-key');
|
|
88
|
+
await client.fetchAttestation(mockRequest);
|
|
89
|
+
const callArgs = fetchStub.firstCall.args[1];
|
|
90
|
+
expect(callArgs.headers['x-api-key']).to.equal('my-secret-key');
|
|
91
|
+
});
|
|
92
|
+
it('should send correct request body', async () => {
|
|
93
|
+
fetchStub.resolves({
|
|
94
|
+
ok: true,
|
|
95
|
+
json: async () => mockResponse,
|
|
96
|
+
});
|
|
97
|
+
const client = new PredicateApiClient('test-api-key');
|
|
98
|
+
await client.fetchAttestation(mockRequest);
|
|
99
|
+
const callArgs = fetchStub.firstCall.args[1];
|
|
100
|
+
const body = JSON.parse(callArgs.body);
|
|
101
|
+
expect(body.to).to.equal(mockRequest.to);
|
|
102
|
+
expect(body.from).to.equal(mockRequest.from);
|
|
103
|
+
expect(body.data).to.equal(mockRequest.data);
|
|
104
|
+
expect(body.msg_value).to.equal(mockRequest.msg_value);
|
|
105
|
+
expect(body.chain).to.equal(mockRequest.chain);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=PredicateApiClient.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateApiClient.test.js","sourceRoot":"","sources":["../../src/predicate/PredicateApiClient.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { PopulatedTransaction } from 'ethers';
|
|
2
|
+
import { Logger } from 'pino';
|
|
3
|
+
import { StaticAggregationHookFactory } from '@hyperlane-xyz/core';
|
|
4
|
+
import { Address } from '@hyperlane-xyz/utils';
|
|
5
|
+
import { MultiProvider } from '../providers/MultiProvider.js';
|
|
6
|
+
import { TokenType } from '../token/config.js';
|
|
7
|
+
import { PredicateWrapperConfig } from '../token/types.js';
|
|
8
|
+
import { ChainName } from '../types.js';
|
|
9
|
+
export interface PredicateWrapperDeploymentResult {
|
|
10
|
+
wrapperAddress: Address;
|
|
11
|
+
aggregationHookAddress: Address;
|
|
12
|
+
setHookTx: PopulatedTransaction;
|
|
13
|
+
}
|
|
14
|
+
export declare class PredicateWrapperDeployer {
|
|
15
|
+
private readonly multiProvider;
|
|
16
|
+
private readonly staticAggregationHookFactory;
|
|
17
|
+
private readonly logger;
|
|
18
|
+
constructor(multiProvider: MultiProvider, staticAggregationHookFactory: StaticAggregationHookFactory, logger?: Logger);
|
|
19
|
+
deployPredicateWrapper(chain: ChainName, warpRouteAddress: Address, config: PredicateWrapperConfig, tokenType?: TokenType): Promise<Address>;
|
|
20
|
+
createAggregationHook(chain: ChainName, predicateWrapperAddress: Address, existingHookAddress: Address): Promise<Address>;
|
|
21
|
+
/**
|
|
22
|
+
* Deploys the predicate wrapper and aggregation hook on-chain as a side effect, then
|
|
23
|
+
* returns the populated setHook transaction for the caller to include in its transaction
|
|
24
|
+
* array.
|
|
25
|
+
*
|
|
26
|
+
* IMPORTANT — irreversible side effects: deployPredicateWrapper submits a real on-chain
|
|
27
|
+
* transaction before this method returns. If the caller discards the returned setHookTx
|
|
28
|
+
* (dry-run, cancellation, error), the PredicateRouterWrapper is orphaned — deployed but
|
|
29
|
+
* unreferenced by any warp route. The aggregation hook is safe because
|
|
30
|
+
* StaticAggregationHookFactory uses CREATE2 (idempotent). Eliminating the wrapper orphan
|
|
31
|
+
* risk requires a CREATE2 factory for PredicateRouterWrapper (future contract work).
|
|
32
|
+
*
|
|
33
|
+
* This differs from EvmHookModule/EvmIsmModule: those modules own the full configuration
|
|
34
|
+
* lifecycle (deploy + configure in one atomic step). Here, deployment is eager but the
|
|
35
|
+
* final wiring (setHook) is deferred to EvmWarpModule.update(), which may choose not to
|
|
36
|
+
* submit it.
|
|
37
|
+
*
|
|
38
|
+
* @param existingHookOverride - When provided, skips the on-chain hook() read and uses
|
|
39
|
+
* this address instead. Pass the pending new hook address when a hook update is being
|
|
40
|
+
* applied in the same update() call to avoid wrapping a stale on-chain hook.
|
|
41
|
+
*/
|
|
42
|
+
deployAndConfigure(chain: ChainName, warpRouteAddress: Address, config: PredicateWrapperConfig, tokenType?: TokenType, existingHookOverride?: Address): Promise<PredicateWrapperDeploymentResult>;
|
|
43
|
+
/**
|
|
44
|
+
* If hookAddress is a StaticAggregationHook that contains a predicate wrapper,
|
|
45
|
+
* strips it and (when multiple non-predicate sub-hooks remain) re-aggregates
|
|
46
|
+
* them via CREATE2 before returning, so the caller can safely wrap the result
|
|
47
|
+
* in a new aggregation without stacking wrappers.
|
|
48
|
+
*
|
|
49
|
+
* Falls back to hookAddress unchanged when:
|
|
50
|
+
* - The address is zero / not an aggregation hook
|
|
51
|
+
* - No predicate wrapper is found among sub-hooks
|
|
52
|
+
* - Multiple non-predicate sub-hooks remain (cannot safely re-aggregate here)
|
|
53
|
+
*/
|
|
54
|
+
private stripPredicateAndReaggregateHook;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=PredicateDeployer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateDeployer.d.ts","sourceRoot":"","sources":["../../src/predicate/PredicateDeployer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAa,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAML,4BAA4B,EAE7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,gCAAgC;IAC/C,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB,EAAE,OAAO,CAAC;IAChC,SAAS,EAAE,oBAAoB,CAAC;CACjC;AAED,qBAAa,wBAAwB;IAIjC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAJ/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAGb,aAAa,EAAE,aAAa,EAC5B,4BAA4B,EAAE,4BAA4B,EAC3E,MAAM,CAAC,EAAE,MAAM;IAMX,sBAAsB,CAC1B,KAAK,EAAE,SAAS,EAChB,gBAAgB,EAAE,OAAO,EACzB,MAAM,EAAE,sBAAsB,EAC9B,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,OAAO,CAAC;IA8Db,qBAAqB,CACzB,KAAK,EAAE,SAAS,EAChB,uBAAuB,EAAE,OAAO,EAChC,mBAAmB,EAAE,OAAO,GAC3B,OAAO,CAAC,OAAO,CAAC;IAkDnB;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,kBAAkB,CACtB,KAAK,EAAE,SAAS,EAChB,gBAAgB,EAAE,OAAO,EACzB,MAAM,EAAE,sBAAsB,EAC9B,SAAS,CAAC,EAAE,SAAS,EACrB,oBAAoB,CAAC,EAAE,OAAO,GAC7B,OAAO,CAAC,gCAAgC,CAAC;IAoE5C;;;;;;;;;;OAUG;YACW,gCAAgC;CA+F/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateDeployer.hardhat-test.d.ts","sourceRoot":"","sources":["../../src/predicate/PredicateDeployer.hardhat-test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { constants } from 'ethers';
|
|
3
|
+
import hre from 'hardhat';
|
|
4
|
+
import { ERC20Test__factory, HypERC20Collateral__factory, MockPredicateRegistry__factory, PredicateRouterWrapper__factory, TokenRouter__factory, } from '@hyperlane-xyz/core';
|
|
5
|
+
import { TestChainName } from '../consts/testChains.js';
|
|
6
|
+
import { TestCoreDeployer } from '../core/TestCoreDeployer.js';
|
|
7
|
+
import { HyperlaneProxyFactoryDeployer } from '../deploy/HyperlaneProxyFactoryDeployer.js';
|
|
8
|
+
import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory.js';
|
|
9
|
+
import { MultiProtocolProvider } from '../providers/MultiProtocolProvider.js';
|
|
10
|
+
import { MultiProvider } from '../providers/MultiProvider.js';
|
|
11
|
+
import { EvmHypCollateralAdapter } from '../token/adapters/EvmTokenAdapter.js';
|
|
12
|
+
import { PredicateWrapperDeployer } from './PredicateDeployer.js';
|
|
13
|
+
describe('PredicateWrapperDeployer', async () => {
|
|
14
|
+
const chain = TestChainName.test1;
|
|
15
|
+
const MOCK_POLICY_ID = 'x-test-policy-123';
|
|
16
|
+
let multiProvider;
|
|
17
|
+
let signer;
|
|
18
|
+
let signerAddress;
|
|
19
|
+
let factoryContracts;
|
|
20
|
+
let mailboxAddress;
|
|
21
|
+
let testTokenAddress;
|
|
22
|
+
let warpRouteAddress;
|
|
23
|
+
let mockPredicateRegistry;
|
|
24
|
+
before(async () => {
|
|
25
|
+
[signer] = await hre.ethers.getSigners();
|
|
26
|
+
signerAddress = await signer.getAddress();
|
|
27
|
+
multiProvider = MultiProvider.createTestMultiProvider({ signer });
|
|
28
|
+
const factoryDeployer = new HyperlaneProxyFactoryDeployer(multiProvider);
|
|
29
|
+
const contractsMap = await factoryDeployer.deploy(multiProvider.mapKnownChains(() => ({})));
|
|
30
|
+
factoryContracts = contractsMap[chain];
|
|
31
|
+
const legacyIsmFactory = new HyperlaneIsmFactory(contractsMap, multiProvider);
|
|
32
|
+
const testCoreDeployer = new TestCoreDeployer(multiProvider, legacyIsmFactory);
|
|
33
|
+
const { mailbox } = (await testCoreDeployer.deployApp()).getContracts(chain);
|
|
34
|
+
mailboxAddress = mailbox.address;
|
|
35
|
+
const testToken = await new ERC20Test__factory(signer).deploy('Test Token', 'TEST', '1000000000000000000000000', 18);
|
|
36
|
+
await testToken.deployed();
|
|
37
|
+
testTokenAddress = testToken.address;
|
|
38
|
+
mockPredicateRegistry = await new MockPredicateRegistry__factory(signer).deploy();
|
|
39
|
+
await mockPredicateRegistry.deployed();
|
|
40
|
+
const collateral = await new HypERC20Collateral__factory(signer).deploy(testTokenAddress, 1, 1, mailboxAddress);
|
|
41
|
+
await collateral.deployed();
|
|
42
|
+
await collateral.initialize(constants.AddressZero, constants.AddressZero, signerAddress);
|
|
43
|
+
warpRouteAddress = collateral.address;
|
|
44
|
+
});
|
|
45
|
+
describe('deployPredicateWrapper', () => {
|
|
46
|
+
it('should deploy PredicateRouterWrapper contract', async () => {
|
|
47
|
+
const deployer = new PredicateWrapperDeployer(multiProvider, factoryContracts.staticAggregationHookFactory);
|
|
48
|
+
const wrapperAddress = await deployer.deployPredicateWrapper(chain, warpRouteAddress, {
|
|
49
|
+
predicateRegistry: mockPredicateRegistry.address,
|
|
50
|
+
policyId: MOCK_POLICY_ID,
|
|
51
|
+
owner: signerAddress,
|
|
52
|
+
});
|
|
53
|
+
expect(wrapperAddress).to.be.properAddress;
|
|
54
|
+
const code = await multiProvider
|
|
55
|
+
.getProvider(chain)
|
|
56
|
+
.getCode(wrapperAddress);
|
|
57
|
+
expect(code).to.not.equal('0x');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe('createAggregationHook', () => {
|
|
61
|
+
it('should create aggregation hook with two hooks', async () => {
|
|
62
|
+
const deployer = new PredicateWrapperDeployer(multiProvider, factoryContracts.staticAggregationHookFactory);
|
|
63
|
+
const wrapperAddress = await deployer.deployPredicateWrapper(chain, warpRouteAddress, {
|
|
64
|
+
predicateRegistry: mockPredicateRegistry.address,
|
|
65
|
+
policyId: MOCK_POLICY_ID,
|
|
66
|
+
owner: signerAddress,
|
|
67
|
+
});
|
|
68
|
+
const existingHookAddress = '0x1234567890123456789012345678901234567890';
|
|
69
|
+
const aggregationHookAddress = await deployer.createAggregationHook(chain, wrapperAddress, existingHookAddress);
|
|
70
|
+
expect(aggregationHookAddress).to.be.properAddress;
|
|
71
|
+
const code = await multiProvider
|
|
72
|
+
.getProvider(chain)
|
|
73
|
+
.getCode(aggregationHookAddress);
|
|
74
|
+
expect(code).to.not.equal('0x');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('deployAndConfigure', () => {
|
|
78
|
+
it('should deploy wrapper and aggregate with mailbox default hook when no existing hook', async () => {
|
|
79
|
+
const newCollateral = await new HypERC20Collateral__factory(signer).deploy(testTokenAddress, 1, 1, mailboxAddress);
|
|
80
|
+
await newCollateral.deployed();
|
|
81
|
+
await newCollateral.initialize(constants.AddressZero, constants.AddressZero, signerAddress);
|
|
82
|
+
const deployer = new PredicateWrapperDeployer(multiProvider, factoryContracts.staticAggregationHookFactory);
|
|
83
|
+
const result = await deployer.deployAndConfigure(chain, newCollateral.address, {
|
|
84
|
+
predicateRegistry: mockPredicateRegistry.address,
|
|
85
|
+
policyId: MOCK_POLICY_ID,
|
|
86
|
+
owner: signerAddress,
|
|
87
|
+
});
|
|
88
|
+
await signer.sendTransaction(result.setHookTx);
|
|
89
|
+
expect(result.wrapperAddress).to.be.properAddress;
|
|
90
|
+
expect(result.aggregationHookAddress).to.be.properAddress;
|
|
91
|
+
// Even with no existing hook, we aggregate with mailbox default hook for gas quoting
|
|
92
|
+
expect(result.wrapperAddress).to.not.equal(result.aggregationHookAddress);
|
|
93
|
+
const router = TokenRouter__factory.connect(newCollateral.address, signer);
|
|
94
|
+
const hookOnRouter = await router.hook();
|
|
95
|
+
expect(hookOnRouter).to.equal(result.aggregationHookAddress);
|
|
96
|
+
});
|
|
97
|
+
it('should create aggregation hook when existing hook is present', async () => {
|
|
98
|
+
const existingHook = await new ERC20Test__factory(signer).deploy('Dummy Hook', 'DH', '0', 18);
|
|
99
|
+
await existingHook.deployed();
|
|
100
|
+
const newCollateral = await new HypERC20Collateral__factory(signer).deploy(testTokenAddress, 1, 1, mailboxAddress);
|
|
101
|
+
await newCollateral.deployed();
|
|
102
|
+
await newCollateral.initialize(existingHook.address, constants.AddressZero, signerAddress);
|
|
103
|
+
const deployer = new PredicateWrapperDeployer(multiProvider, factoryContracts.staticAggregationHookFactory);
|
|
104
|
+
const result = await deployer.deployAndConfigure(chain, newCollateral.address, {
|
|
105
|
+
predicateRegistry: mockPredicateRegistry.address,
|
|
106
|
+
policyId: MOCK_POLICY_ID,
|
|
107
|
+
owner: signerAddress,
|
|
108
|
+
});
|
|
109
|
+
await signer.sendTransaction(result.setHookTx);
|
|
110
|
+
expect(result.wrapperAddress).to.not.equal(result.aggregationHookAddress);
|
|
111
|
+
const router = TokenRouter__factory.connect(newCollateral.address, signer);
|
|
112
|
+
const hookOnRouter = await router.hook();
|
|
113
|
+
expect(hookOnRouter).to.equal(result.aggregationHookAddress);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('Adapter Predicate Support', () => {
|
|
117
|
+
let wrapperAddress;
|
|
118
|
+
let collateralWithWrapper;
|
|
119
|
+
let multiProtocolProvider;
|
|
120
|
+
before(async () => {
|
|
121
|
+
multiProtocolProvider =
|
|
122
|
+
MultiProtocolProvider.fromMultiProvider(multiProvider);
|
|
123
|
+
collateralWithWrapper = await new HypERC20Collateral__factory(signer).deploy(testTokenAddress, 1, 1, mailboxAddress);
|
|
124
|
+
await collateralWithWrapper.deployed();
|
|
125
|
+
await collateralWithWrapper.initialize(constants.AddressZero, constants.AddressZero, signerAddress);
|
|
126
|
+
const deployer = new PredicateWrapperDeployer(multiProvider, factoryContracts.staticAggregationHookFactory);
|
|
127
|
+
const result = await deployer.deployAndConfigure(chain, collateralWithWrapper.address, {
|
|
128
|
+
predicateRegistry: mockPredicateRegistry.address,
|
|
129
|
+
policyId: MOCK_POLICY_ID,
|
|
130
|
+
owner: signerAddress,
|
|
131
|
+
});
|
|
132
|
+
await signer.sendTransaction(result.setHookTx);
|
|
133
|
+
wrapperAddress = result.wrapperAddress;
|
|
134
|
+
});
|
|
135
|
+
it('should detect PredicateRouterWrapper on collateral adapter', async () => {
|
|
136
|
+
const adapter = new EvmHypCollateralAdapter(chain, multiProtocolProvider, {
|
|
137
|
+
token: collateralWithWrapper.address,
|
|
138
|
+
});
|
|
139
|
+
const detectedWrapper = await adapter.getPredicateWrapperAddress();
|
|
140
|
+
expect(detectedWrapper).to.equal(wrapperAddress);
|
|
141
|
+
});
|
|
142
|
+
it('should return null when no PredicateRouterWrapper present', async () => {
|
|
143
|
+
const adapter = new EvmHypCollateralAdapter(chain, multiProtocolProvider, {
|
|
144
|
+
token: warpRouteAddress,
|
|
145
|
+
});
|
|
146
|
+
const detectedWrapper = await adapter.getPredicateWrapperAddress();
|
|
147
|
+
expect(detectedWrapper).to.be.null;
|
|
148
|
+
});
|
|
149
|
+
it('should route approval to wrapper when wrapper present', async () => {
|
|
150
|
+
const adapter = new EvmHypCollateralAdapter(chain, multiProtocolProvider, {
|
|
151
|
+
token: collateralWithWrapper.address,
|
|
152
|
+
});
|
|
153
|
+
const approveTx = await adapter.populateApproveTx({
|
|
154
|
+
weiAmountOrId: '1000000',
|
|
155
|
+
recipient: collateralWithWrapper.address,
|
|
156
|
+
});
|
|
157
|
+
expect(approveTx.to?.toLowerCase()).to.equal(testTokenAddress.toLowerCase());
|
|
158
|
+
expect(approveTx.data).to.include(wrapperAddress.slice(2).toLowerCase());
|
|
159
|
+
});
|
|
160
|
+
it('should throw error when attestation provided but no wrapper', async () => {
|
|
161
|
+
const adapter = new EvmHypCollateralAdapter(chain, multiProtocolProvider, {
|
|
162
|
+
token: warpRouteAddress,
|
|
163
|
+
});
|
|
164
|
+
const mockAttestation = {
|
|
165
|
+
uuid: 'test-uuid',
|
|
166
|
+
expiration: Math.floor(Date.now() / 1000) + 3600,
|
|
167
|
+
attester: signerAddress,
|
|
168
|
+
signature: '0x1234',
|
|
169
|
+
};
|
|
170
|
+
try {
|
|
171
|
+
await adapter.populateTransferRemoteTx({
|
|
172
|
+
weiAmountOrId: '1000000',
|
|
173
|
+
destination: 2,
|
|
174
|
+
recipient: signerAddress,
|
|
175
|
+
attestation: mockAttestation,
|
|
176
|
+
});
|
|
177
|
+
expect.fail('Expected error to be thrown');
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
expect(error.message).to.include('Attestation provided but no PredicateRouterWrapper detected');
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
it('should populate transferRemoteWithAttestation when attestation provided', async () => {
|
|
184
|
+
const adapter = new EvmHypCollateralAdapter(chain, multiProtocolProvider, {
|
|
185
|
+
token: collateralWithWrapper.address,
|
|
186
|
+
});
|
|
187
|
+
const mockAttestation = {
|
|
188
|
+
uuid: 'test-uuid',
|
|
189
|
+
expiration: Math.floor(Date.now() / 1000) + 3600,
|
|
190
|
+
attester: signerAddress,
|
|
191
|
+
signature: '0x1234',
|
|
192
|
+
};
|
|
193
|
+
const tx = await adapter.populateTransferRemoteTx({
|
|
194
|
+
weiAmountOrId: '1000000',
|
|
195
|
+
destination: 2,
|
|
196
|
+
recipient: signerAddress,
|
|
197
|
+
attestation: mockAttestation,
|
|
198
|
+
interchainGas: {
|
|
199
|
+
igpQuote: { amount: 0n },
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
expect(tx.to?.toLowerCase()).to.equal(wrapperAddress.toLowerCase());
|
|
203
|
+
const iface = PredicateRouterWrapper__factory.createInterface();
|
|
204
|
+
const selector = iface.getSighash('transferRemoteWithAttestation');
|
|
205
|
+
expect(tx.data?.startsWith(selector)).to.be.true;
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
//# sourceMappingURL=PredicateDeployer.hardhat-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PredicateDeployer.hardhat-test.js","sourceRoot":"","sources":["../../src/predicate/PredicateDeployer.hardhat-test.ts"],"names":[],"mappings":"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"}
|