@agirails/sdk 2.0.0-beta

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.
Files changed (154) hide show
  1. package/README.md +183 -0
  2. package/dist/ACTPClient.d.ts +52 -0
  3. package/dist/ACTPClient.d.ts.map +1 -0
  4. package/dist/ACTPClient.js +120 -0
  5. package/dist/ACTPClient.js.map +1 -0
  6. package/dist/abi/ACTPKernel.json +1340 -0
  7. package/dist/abi/ERC20.json +38 -0
  8. package/dist/abi/EscrowVault.json +64 -0
  9. package/dist/builders/DeliveryProofBuilder.d.ts +37 -0
  10. package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -0
  11. package/dist/builders/DeliveryProofBuilder.js +165 -0
  12. package/dist/builders/DeliveryProofBuilder.js.map +1 -0
  13. package/dist/builders/QuoteBuilder.d.ts +68 -0
  14. package/dist/builders/QuoteBuilder.d.ts.map +1 -0
  15. package/dist/builders/QuoteBuilder.js +255 -0
  16. package/dist/builders/QuoteBuilder.js.map +1 -0
  17. package/dist/builders/index.d.ts +3 -0
  18. package/dist/builders/index.d.ts.map +1 -0
  19. package/dist/builders/index.js +10 -0
  20. package/dist/builders/index.js.map +1 -0
  21. package/dist/config/networks.d.ts +27 -0
  22. package/dist/config/networks.d.ts.map +1 -0
  23. package/dist/config/networks.js +103 -0
  24. package/dist/config/networks.js.map +1 -0
  25. package/dist/errors/index.d.ts +38 -0
  26. package/dist/errors/index.d.ts.map +1 -0
  27. package/dist/errors/index.js +87 -0
  28. package/dist/errors/index.js.map +1 -0
  29. package/dist/index.d.ts +19 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +68 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/protocol/ACTPKernel.d.ts +30 -0
  34. package/dist/protocol/ACTPKernel.d.ts.map +1 -0
  35. package/dist/protocol/ACTPKernel.js +261 -0
  36. package/dist/protocol/ACTPKernel.js.map +1 -0
  37. package/dist/protocol/EASHelper.d.ts +23 -0
  38. package/dist/protocol/EASHelper.d.ts.map +1 -0
  39. package/dist/protocol/EASHelper.js +106 -0
  40. package/dist/protocol/EASHelper.js.map +1 -0
  41. package/dist/protocol/EscrowVault.d.ts +24 -0
  42. package/dist/protocol/EscrowVault.d.ts.map +1 -0
  43. package/dist/protocol/EscrowVault.js +114 -0
  44. package/dist/protocol/EscrowVault.js.map +1 -0
  45. package/dist/protocol/EventMonitor.d.ts +18 -0
  46. package/dist/protocol/EventMonitor.d.ts.map +1 -0
  47. package/dist/protocol/EventMonitor.js +92 -0
  48. package/dist/protocol/EventMonitor.js.map +1 -0
  49. package/dist/protocol/MessageSigner.d.ts +23 -0
  50. package/dist/protocol/MessageSigner.d.ts.map +1 -0
  51. package/dist/protocol/MessageSigner.js +178 -0
  52. package/dist/protocol/MessageSigner.js.map +1 -0
  53. package/dist/protocol/ProofGenerator.d.ts +22 -0
  54. package/dist/protocol/ProofGenerator.d.ts.map +1 -0
  55. package/dist/protocol/ProofGenerator.js +64 -0
  56. package/dist/protocol/ProofGenerator.js.map +1 -0
  57. package/dist/protocol/QuoteBuilder.d.ts +2 -0
  58. package/dist/protocol/QuoteBuilder.d.ts.map +1 -0
  59. package/dist/protocol/QuoteBuilder.js +7 -0
  60. package/dist/protocol/QuoteBuilder.js.map +1 -0
  61. package/dist/types/eip712.d.ts +106 -0
  62. package/dist/types/eip712.d.ts.map +1 -0
  63. package/dist/types/eip712.js +84 -0
  64. package/dist/types/eip712.js.map +1 -0
  65. package/dist/types/escrow.d.ts +18 -0
  66. package/dist/types/escrow.d.ts.map +1 -0
  67. package/dist/types/escrow.js +3 -0
  68. package/dist/types/escrow.js.map +1 -0
  69. package/dist/types/index.d.ts +6 -0
  70. package/dist/types/index.d.ts.map +1 -0
  71. package/dist/types/index.js +22 -0
  72. package/dist/types/index.js.map +1 -0
  73. package/dist/types/message.d.ts +109 -0
  74. package/dist/types/message.d.ts.map +1 -0
  75. package/dist/types/message.js +3 -0
  76. package/dist/types/message.js.map +1 -0
  77. package/dist/types/state.d.ts +19 -0
  78. package/dist/types/state.d.ts.map +1 -0
  79. package/dist/types/state.js +49 -0
  80. package/dist/types/state.js.map +1 -0
  81. package/dist/types/transaction.d.ts +36 -0
  82. package/dist/types/transaction.d.ts.map +1 -0
  83. package/dist/types/transaction.js +3 -0
  84. package/dist/types/transaction.js.map +1 -0
  85. package/dist/utils/IPFSClient.d.ts +37 -0
  86. package/dist/utils/IPFSClient.d.ts.map +1 -0
  87. package/dist/utils/IPFSClient.js +128 -0
  88. package/dist/utils/IPFSClient.js.map +1 -0
  89. package/dist/utils/NonceManager.d.ts +34 -0
  90. package/dist/utils/NonceManager.d.ts.map +1 -0
  91. package/dist/utils/NonceManager.js +114 -0
  92. package/dist/utils/NonceManager.js.map +1 -0
  93. package/dist/utils/ReceivedNonceTracker.d.ts +35 -0
  94. package/dist/utils/ReceivedNonceTracker.d.ts.map +1 -0
  95. package/dist/utils/ReceivedNonceTracker.js +196 -0
  96. package/dist/utils/ReceivedNonceTracker.js.map +1 -0
  97. package/dist/utils/canonicalJson.d.ts +4 -0
  98. package/dist/utils/canonicalJson.d.ts.map +1 -0
  99. package/dist/utils/canonicalJson.js +21 -0
  100. package/dist/utils/canonicalJson.js.map +1 -0
  101. package/dist/utils/computeTypeHash.d.ts +3 -0
  102. package/dist/utils/computeTypeHash.d.ts.map +1 -0
  103. package/dist/utils/computeTypeHash.js +30 -0
  104. package/dist/utils/computeTypeHash.js.map +1 -0
  105. package/dist/utils/validation.d.ts +6 -0
  106. package/dist/utils/validation.d.ts.map +1 -0
  107. package/dist/utils/validation.js +46 -0
  108. package/dist/utils/validation.js.map +1 -0
  109. package/package.json +73 -0
  110. package/src/ACTPClient.ts +276 -0
  111. package/src/__tests__/ProofGenerator.test.ts +124 -0
  112. package/src/__tests__/QuoteBuilder.test.ts +516 -0
  113. package/src/__tests__/StateMachine.test.ts +82 -0
  114. package/src/__tests__/builders/DeliveryProofBuilder.test.ts +581 -0
  115. package/src/__tests__/integration/ACTPClient.test.ts +263 -0
  116. package/src/__tests__/integration.test.ts +289 -0
  117. package/src/__tests__/protocol/EASHelper.test.ts +472 -0
  118. package/src/__tests__/protocol/EventMonitor.test.ts +382 -0
  119. package/src/__tests__/security/ACTPKernel.security.test.ts +1167 -0
  120. package/src/__tests__/security/EscrowVault.security.test.ts +570 -0
  121. package/src/__tests__/security/MessageSigner.security.test.ts +286 -0
  122. package/src/__tests__/security/NonceReplay.security.test.ts +501 -0
  123. package/src/__tests__/security/validation.security.test.ts +376 -0
  124. package/src/__tests__/utils/IPFSClient.test.ts +262 -0
  125. package/src/__tests__/utils/NonceManager.test.ts +205 -0
  126. package/src/__tests__/utils/canonicalJson.test.ts +153 -0
  127. package/src/abi/ACTPKernel.json +1340 -0
  128. package/src/abi/ERC20.json +40 -0
  129. package/src/abi/EscrowVault.json +66 -0
  130. package/src/builders/DeliveryProofBuilder.ts +326 -0
  131. package/src/builders/QuoteBuilder.ts +483 -0
  132. package/src/builders/index.ts +17 -0
  133. package/src/config/networks.ts +165 -0
  134. package/src/errors/index.ts +130 -0
  135. package/src/index.ts +108 -0
  136. package/src/protocol/ACTPKernel.ts +625 -0
  137. package/src/protocol/EASHelper.ts +197 -0
  138. package/src/protocol/EscrowVault.ts +237 -0
  139. package/src/protocol/EventMonitor.ts +161 -0
  140. package/src/protocol/MessageSigner.ts +336 -0
  141. package/src/protocol/ProofGenerator.ts +119 -0
  142. package/src/protocol/QuoteBuilder.ts +15 -0
  143. package/src/types/eip712.ts +175 -0
  144. package/src/types/escrow.ts +26 -0
  145. package/src/types/index.ts +10 -0
  146. package/src/types/message.ts +145 -0
  147. package/src/types/state.ts +77 -0
  148. package/src/types/transaction.ts +54 -0
  149. package/src/utils/IPFSClient.ts +248 -0
  150. package/src/utils/NonceManager.ts +293 -0
  151. package/src/utils/ReceivedNonceTracker.ts +397 -0
  152. package/src/utils/canonicalJson.ts +38 -0
  153. package/src/utils/computeTypeHash.ts +50 -0
  154. package/src/utils/validation.ts +82 -0
@@ -0,0 +1,38 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ { "name": "spender", "type": "address" },
5
+ { "name": "amount", "type": "uint256" }
6
+ ],
7
+ "name": "approve",
8
+ "outputs": [{ "name": "", "type": "bool" }],
9
+ "stateMutability": "nonpayable",
10
+ "type": "function"
11
+ },
12
+ {
13
+ "inputs": [
14
+ { "name": "account", "type": "address" }
15
+ ],
16
+ "name": "balanceOf",
17
+ "outputs": [{ "name": "", "type": "uint256" }],
18
+ "stateMutability": "view",
19
+ "type": "function"
20
+ },
21
+ {
22
+ "inputs": [
23
+ { "name": "owner", "type": "address" },
24
+ { "name": "spender", "type": "address" }
25
+ ],
26
+ "name": "allowance",
27
+ "outputs": [{ "name": "", "type": "uint256" }],
28
+ "stateMutability": "view",
29
+ "type": "function"
30
+ },
31
+ {
32
+ "inputs": [],
33
+ "name": "decimals",
34
+ "outputs": [{ "name": "", "type": "uint8" }],
35
+ "stateMutability": "view",
36
+ "type": "function"
37
+ }
38
+ ]
@@ -0,0 +1,64 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ { "name": "kernel", "type": "address" },
5
+ { "name": "txId", "type": "bytes32" },
6
+ { "name": "token", "type": "address" },
7
+ { "name": "amount", "type": "uint256" },
8
+ { "name": "beneficiary", "type": "address" }
9
+ ],
10
+ "name": "createEscrow",
11
+ "outputs": [{ "name": "escrowId", "type": "bytes32" }],
12
+ "stateMutability": "nonpayable",
13
+ "type": "function"
14
+ },
15
+ {
16
+ "inputs": [
17
+ { "name": "escrowId", "type": "bytes32" },
18
+ { "name": "recipients", "type": "address[]" },
19
+ { "name": "amounts", "type": "uint256[]" }
20
+ ],
21
+ "name": "disburse",
22
+ "outputs": [],
23
+ "stateMutability": "nonpayable",
24
+ "type": "function"
25
+ },
26
+ {
27
+ "inputs": [
28
+ { "name": "escrowId", "type": "bytes32" }
29
+ ],
30
+ "name": "escrows",
31
+ "outputs": [
32
+ { "name": "kernel", "type": "address" },
33
+ { "name": "txId", "type": "bytes32" },
34
+ { "name": "token", "type": "address" },
35
+ { "name": "amount", "type": "uint256" },
36
+ { "name": "beneficiary", "type": "address" },
37
+ { "name": "released", "type": "bool" }
38
+ ],
39
+ "stateMutability": "view",
40
+ "type": "function"
41
+ },
42
+ {
43
+ "anonymous": false,
44
+ "inputs": [
45
+ { "indexed": true, "name": "escrowId", "type": "bytes32" },
46
+ { "indexed": true, "name": "kernel", "type": "address" },
47
+ { "indexed": true, "name": "txId", "type": "bytes32" },
48
+ { "indexed": false, "name": "token", "type": "address" },
49
+ { "indexed": false, "name": "amount", "type": "uint256" }
50
+ ],
51
+ "name": "EscrowCreated",
52
+ "type": "event"
53
+ },
54
+ {
55
+ "anonymous": false,
56
+ "inputs": [
57
+ { "indexed": true, "name": "escrowId", "type": "bytes32" },
58
+ { "indexed": false, "name": "recipients", "type": "address[]" },
59
+ { "indexed": false, "name": "amounts", "type": "uint256[]" }
60
+ ],
61
+ "name": "EscrowReleased",
62
+ "type": "event"
63
+ }
64
+ ]
@@ -0,0 +1,37 @@
1
+ import { Signer } from 'ethers';
2
+ import { EAS } from '@ethereum-attestation-service/eas-sdk';
3
+ import { IPFSClient } from '../utils/IPFSClient';
4
+ import { NonceManager } from '../utils/NonceManager';
5
+ import { DeliveryProofMessage } from '../types/message';
6
+ export declare const AGIRAILS_DELIVERY_SCHEMA_UID = "0x0000000000000000000000000000000000000000000000000000000000000000";
7
+ export interface DeliveryProofParams {
8
+ txId: string;
9
+ provider: string;
10
+ consumer: string;
11
+ resultData: any;
12
+ metadata?: {
13
+ executionTime?: number;
14
+ outputFormat?: string;
15
+ outputSize?: number;
16
+ notes?: string;
17
+ };
18
+ chainId: number;
19
+ kernelAddress: string;
20
+ }
21
+ export declare class DeliveryProofBuilder {
22
+ private ipfs;
23
+ private signer;
24
+ private nonceManager;
25
+ private eas;
26
+ constructor(ipfs: IPFSClient, signer: Signer, nonceManager: NonceManager, eas: EAS);
27
+ build(params: DeliveryProofParams): Promise<{
28
+ deliveryProof: DeliveryProofMessage;
29
+ deliveryProofCID: string;
30
+ attestationUID: string;
31
+ }>;
32
+ verify(deliveryProof: DeliveryProofMessage, resultData: any, kernelAddress: string): Promise<boolean>;
33
+ private signDeliveryProof;
34
+ private recoverDeliveryProofSigner;
35
+ private extractAddressFromDID;
36
+ }
37
+ //# sourceMappingURL=DeliveryProofBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeliveryProofBuilder.d.ts","sourceRoot":"","sources":["../../src/builders/DeliveryProofBuilder.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,MAAM,EAAmB,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,GAAG,EAAiB,MAAM,uCAAuC,CAAC;AAE3E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAOxD,eAAO,MAAM,4BAA4B,uEAAuE,CAAC;AAKjH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,GAAG,CAAC;IAChB,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAOD,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,GAAG;gBAHH,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,GAAG;IAUZ,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC;QAChD,aAAa,EAAE,oBAAoB,CAAC;QACpC,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAmFI,MAAM,CACV,aAAa,EAAE,oBAAoB,EACnC,UAAU,EAAE,GAAG,EACf,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,OAAO,CAAC;YAqEL,iBAAiB;YA6CjB,0BAA0B;IA+CxC,OAAO,CAAC,qBAAqB;CAU9B"}
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryProofBuilder = exports.AGIRAILS_DELIVERY_SCHEMA_UID = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const eas_sdk_1 = require("@ethereum-attestation-service/eas-sdk");
6
+ const canonicalJson_1 = require("../utils/canonicalJson");
7
+ const eip712_1 = require("../types/eip712");
8
+ exports.AGIRAILS_DELIVERY_SCHEMA_UID = '0x0000000000000000000000000000000000000000000000000000000000000000';
9
+ class DeliveryProofBuilder {
10
+ constructor(ipfs, signer, nonceManager, eas) {
11
+ this.ipfs = ipfs;
12
+ this.signer = signer;
13
+ this.nonceManager = nonceManager;
14
+ this.eas = eas;
15
+ }
16
+ async build(params) {
17
+ const resultCID = await this.ipfs.add(JSON.stringify(params.resultData));
18
+ await this.ipfs.pin(resultCID);
19
+ const resultHash = (0, canonicalJson_1.computeResultHash)(params.resultData);
20
+ const deliveredAt = Math.floor(Date.now() / 1000);
21
+ const schemaEncoder = new eas_sdk_1.SchemaEncoder('bytes32 txId,string resultCID,bytes32 resultHash,uint256 deliveredAt');
22
+ const consumerAddress = this.extractAddressFromDID(params.consumer);
23
+ const encodedData = schemaEncoder.encodeData([
24
+ { name: 'txId', value: params.txId, type: 'bytes32' },
25
+ { name: 'resultCID', value: resultCID, type: 'string' },
26
+ { name: 'resultHash', value: resultHash, type: 'bytes32' },
27
+ { name: 'deliveredAt', value: deliveredAt, type: 'uint256' }
28
+ ]);
29
+ const tx = await this.eas.attest({
30
+ schema: exports.AGIRAILS_DELIVERY_SCHEMA_UID,
31
+ data: {
32
+ recipient: consumerAddress,
33
+ expirationTime: 0n,
34
+ revocable: false,
35
+ data: encodedData
36
+ }
37
+ });
38
+ const receipt = await tx.wait();
39
+ const attestationUID = receipt.newAttestationUID || receipt;
40
+ const deliveryProof = {
41
+ type: 'agirails.delivery.v1',
42
+ version: '1.0.0',
43
+ txId: params.txId,
44
+ provider: params.provider,
45
+ consumer: params.consumer,
46
+ resultCID,
47
+ resultHash,
48
+ metadata: params.metadata || {},
49
+ easAttestationUID: attestationUID,
50
+ deliveredAt,
51
+ chainId: params.chainId,
52
+ nonce: this.nonceManager.getNextNonce('agirails.delivery.v1'),
53
+ signature: ''
54
+ };
55
+ const signature = await this.signDeliveryProof(deliveryProof, params.kernelAddress);
56
+ deliveryProof.signature = signature;
57
+ const deliveryProofCID = await this.ipfs.add(JSON.stringify(deliveryProof));
58
+ await this.ipfs.pin(deliveryProofCID);
59
+ this.nonceManager.recordNonce('agirails.delivery.v1', deliveryProof.nonce);
60
+ return {
61
+ deliveryProof,
62
+ deliveryProofCID,
63
+ attestationUID
64
+ };
65
+ }
66
+ async verify(deliveryProof, resultData, kernelAddress) {
67
+ const recoveredAddress = await this.recoverDeliveryProofSigner(deliveryProof, kernelAddress);
68
+ const expectedAddress = this.extractAddressFromDID(deliveryProof.provider);
69
+ if (recoveredAddress.toLowerCase() !== expectedAddress.toLowerCase()) {
70
+ throw new Error('Invalid signature: recovered address does not match provider');
71
+ }
72
+ const computedHash = (0, canonicalJson_1.computeResultHash)(resultData);
73
+ if (computedHash !== deliveryProof.resultHash) {
74
+ throw new Error('Result hash mismatch - data may be tampered');
75
+ }
76
+ const attestation = await this.eas.getAttestation(deliveryProof.easAttestationUID);
77
+ if (!attestation) {
78
+ throw new Error('Attestation not found on EAS');
79
+ }
80
+ if (attestation.schema !== exports.AGIRAILS_DELIVERY_SCHEMA_UID) {
81
+ throw new Error(`Invalid attestation schema: expected ${exports.AGIRAILS_DELIVERY_SCHEMA_UID}, got ${attestation.schema}`);
82
+ }
83
+ if ('revoked' in attestation && attestation.revoked) {
84
+ throw new Error('Attestation was revoked');
85
+ }
86
+ if ('revocationTime' in attestation && attestation.revocationTime > 0) {
87
+ throw new Error('Attestation was revoked');
88
+ }
89
+ const schemaEncoder = new eas_sdk_1.SchemaEncoder('bytes32 txId,string resultCID,bytes32 resultHash,uint256 deliveredAt');
90
+ const decodedData = schemaEncoder.decodeData(attestation.data);
91
+ const attestationTxId = decodedData.find((d) => d.name === 'txId')?.value.value;
92
+ const attestationResultCID = decodedData.find((d) => d.name === 'resultCID')?.value.value;
93
+ const attestationResultHash = decodedData.find((d) => d.name === 'resultHash')?.value.value;
94
+ if (attestationTxId !== deliveryProof.txId) {
95
+ throw new Error('Attestation txId mismatch');
96
+ }
97
+ if (attestationResultCID !== deliveryProof.resultCID) {
98
+ throw new Error('Attestation resultCID mismatch');
99
+ }
100
+ if (attestationResultHash !== deliveryProof.resultHash) {
101
+ throw new Error('Attestation resultHash mismatch');
102
+ }
103
+ return true;
104
+ }
105
+ async signDeliveryProof(deliveryProof, kernelAddress) {
106
+ const domain = {
107
+ name: 'AGIRAILS',
108
+ version: '1',
109
+ chainId: deliveryProof.chainId,
110
+ verifyingContract: kernelAddress
111
+ };
112
+ const message = {
113
+ txId: deliveryProof.txId,
114
+ provider: deliveryProof.provider,
115
+ consumer: deliveryProof.consumer,
116
+ resultCID: deliveryProof.resultCID,
117
+ resultHash: deliveryProof.resultHash,
118
+ easAttestationUID: deliveryProof.easAttestationUID,
119
+ deliveredAt: deliveryProof.deliveredAt,
120
+ chainId: deliveryProof.chainId,
121
+ nonce: deliveryProof.nonce
122
+ };
123
+ if ('signTypedData' in this.signer && typeof this.signer.signTypedData === 'function') {
124
+ const signature = await this.signer.signTypedData(domain, eip712_1.AIP4DeliveryProofTypes, message);
125
+ return signature;
126
+ }
127
+ throw new Error('Signer does not support EIP-712 typed data signing (ethers v6+)');
128
+ }
129
+ async recoverDeliveryProofSigner(deliveryProof, kernelAddress) {
130
+ const domain = {
131
+ name: 'AGIRAILS',
132
+ version: '1',
133
+ chainId: deliveryProof.chainId,
134
+ verifyingContract: kernelAddress
135
+ };
136
+ const message = {
137
+ txId: deliveryProof.txId,
138
+ provider: deliveryProof.provider,
139
+ consumer: deliveryProof.consumer,
140
+ resultCID: deliveryProof.resultCID,
141
+ resultHash: deliveryProof.resultHash,
142
+ easAttestationUID: deliveryProof.easAttestationUID,
143
+ deliveredAt: deliveryProof.deliveredAt,
144
+ chainId: deliveryProof.chainId,
145
+ nonce: deliveryProof.nonce
146
+ };
147
+ try {
148
+ const recoveredAddress = (0, ethers_1.verifyTypedData)(domain, eip712_1.AIP4DeliveryProofTypes, message, deliveryProof.signature);
149
+ return recoveredAddress;
150
+ }
151
+ catch (error) {
152
+ throw new Error(`Invalid signature: ${error.message || 'signature verification failed'}`);
153
+ }
154
+ }
155
+ extractAddressFromDID(did) {
156
+ const parts = did.replace('did:ethr:', '').split(':');
157
+ const address = parts.length === 2 ? parts[1] : parts[0];
158
+ if (!address.startsWith('0x') || address.length !== 42) {
159
+ throw new Error(`Invalid DID format: ${did}`);
160
+ }
161
+ return address;
162
+ }
163
+ }
164
+ exports.DeliveryProofBuilder = DeliveryProofBuilder;
165
+ //# sourceMappingURL=DeliveryProofBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeliveryProofBuilder.js","sourceRoot":"","sources":["../../src/builders/DeliveryProofBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { Signer } from 'ethers';
2
+ import { IPFSClient } from '../utils/IPFSClient';
3
+ import { NonceManager } from '../utils/NonceManager';
4
+ export interface QuoteMessage {
5
+ type: 'agirails.quote.v1';
6
+ version: '1.0.0';
7
+ txId: string;
8
+ provider: string;
9
+ consumer: string;
10
+ quotedAmount: string;
11
+ originalAmount: string;
12
+ maxPrice: string;
13
+ currency: string;
14
+ decimals: number;
15
+ quotedAt: number;
16
+ expiresAt: number;
17
+ justification?: {
18
+ reason?: string;
19
+ estimatedTime?: number;
20
+ computeCost?: number;
21
+ breakdown?: Record<string, any>;
22
+ };
23
+ chainId: number;
24
+ nonce: number;
25
+ signature: string;
26
+ }
27
+ export interface QuoteParams {
28
+ txId: string;
29
+ provider: string;
30
+ consumer: string;
31
+ quotedAmount: string;
32
+ originalAmount: string;
33
+ maxPrice: string;
34
+ currency?: string;
35
+ decimals?: number;
36
+ expiresAt?: number;
37
+ justification?: {
38
+ reason?: string;
39
+ estimatedTime?: number;
40
+ computeCost?: number;
41
+ breakdown?: Record<string, any>;
42
+ };
43
+ chainId: number;
44
+ kernelAddress: string;
45
+ }
46
+ export declare const AIP2QuoteTypes: {
47
+ PriceQuote: {
48
+ name: string;
49
+ type: string;
50
+ }[];
51
+ };
52
+ export declare class QuoteBuilder {
53
+ private signer;
54
+ private nonceManager;
55
+ private ipfs?;
56
+ constructor(signer: Signer, nonceManager: NonceManager, ipfs?: IPFSClient | undefined);
57
+ build(params: QuoteParams): Promise<QuoteMessage>;
58
+ verify(quote: QuoteMessage, kernelAddress: string): Promise<boolean>;
59
+ uploadToIPFS(quote: QuoteMessage): Promise<string>;
60
+ computeHash(quote: QuoteMessage): string;
61
+ private signQuote;
62
+ private recoverQuoteSigner;
63
+ private computeJustificationHash;
64
+ private validateParams;
65
+ private validateQuoteSchema;
66
+ private extractAddressFromDID;
67
+ }
68
+ //# sourceMappingURL=QuoteBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuoteBuilder.d.ts","sourceRoot":"","sources":["../../src/builders/QuoteBuilder.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,MAAM,EAA2C,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAQrD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,eAAO,MAAM,cAAc;;;;;CAgB1B,CAAC;AAMF,qBAAa,YAAY;IAErB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,IAAI,CAAC;gBAFL,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,IAAI,CAAC,EAAE,UAAU,YAAA;IAUrB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAsDjD,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmDpE,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBxD,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM;YAc1B,SAAS;IA4CvB,OAAO,CAAC,kBAAkB;IA+C1B,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,cAAc;IA6DtB,OAAO,CAAC,mBAAmB;IA0D3B,OAAO,CAAC,qBAAqB;CAU9B"}
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuoteBuilder = exports.AIP2QuoteTypes = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const canonicalJson_1 = require("../utils/canonicalJson");
6
+ const errors_1 = require("../errors");
7
+ exports.AIP2QuoteTypes = {
8
+ PriceQuote: [
9
+ { name: 'txId', type: 'bytes32' },
10
+ { name: 'provider', type: 'string' },
11
+ { name: 'consumer', type: 'string' },
12
+ { name: 'quotedAmount', type: 'string' },
13
+ { name: 'originalAmount', type: 'string' },
14
+ { name: 'maxPrice', type: 'string' },
15
+ { name: 'currency', type: 'string' },
16
+ { name: 'decimals', type: 'uint8' },
17
+ { name: 'quotedAt', type: 'uint256' },
18
+ { name: 'expiresAt', type: 'uint256' },
19
+ { name: 'justificationHash', type: 'bytes32' },
20
+ { name: 'chainId', type: 'uint256' },
21
+ { name: 'nonce', type: 'uint256' }
22
+ ]
23
+ };
24
+ class QuoteBuilder {
25
+ constructor(signer, nonceManager, ipfs) {
26
+ this.signer = signer;
27
+ this.nonceManager = nonceManager;
28
+ this.ipfs = ipfs;
29
+ }
30
+ async build(params) {
31
+ this.validateParams(params);
32
+ const quotedAt = Math.floor(Date.now() / 1000);
33
+ const expiresAt = params.expiresAt || (quotedAt + 3600);
34
+ if (expiresAt <= quotedAt) {
35
+ throw new Error('expiresAt must be after quotedAt');
36
+ }
37
+ if (expiresAt > quotedAt + 86400) {
38
+ throw new Error('expiresAt cannot exceed 24 hours from quotedAt');
39
+ }
40
+ const quote = {
41
+ type: 'agirails.quote.v1',
42
+ version: '1.0.0',
43
+ txId: params.txId,
44
+ provider: params.provider,
45
+ consumer: params.consumer,
46
+ quotedAmount: params.quotedAmount,
47
+ originalAmount: params.originalAmount,
48
+ maxPrice: params.maxPrice,
49
+ currency: params.currency || 'USDC',
50
+ decimals: params.decimals !== undefined ? params.decimals : 6,
51
+ quotedAt,
52
+ expiresAt,
53
+ justification: params.justification,
54
+ chainId: params.chainId,
55
+ nonce: this.nonceManager.getNextNonce('agirails.quote.v1'),
56
+ signature: ''
57
+ };
58
+ const signature = await this.signQuote(quote, params.kernelAddress);
59
+ quote.signature = signature;
60
+ this.nonceManager.recordNonce('agirails.quote.v1', quote.nonce);
61
+ return quote;
62
+ }
63
+ async verify(quote, kernelAddress) {
64
+ this.validateQuoteSchema(quote);
65
+ const recoveredAddress = this.recoverQuoteSigner(quote, kernelAddress);
66
+ const expectedAddress = this.extractAddressFromDID(quote.provider);
67
+ if (recoveredAddress.toLowerCase() !== expectedAddress.toLowerCase()) {
68
+ throw new Error('Invalid signature: recovered address does not match provider');
69
+ }
70
+ const quotedAmount = BigInt(quote.quotedAmount);
71
+ const originalAmount = BigInt(quote.originalAmount);
72
+ const maxPrice = BigInt(quote.maxPrice);
73
+ if (quotedAmount < originalAmount) {
74
+ throw new Error('Quoted amount below original amount');
75
+ }
76
+ if (quotedAmount > maxPrice) {
77
+ throw new Error('Quoted amount exceeds maxPrice');
78
+ }
79
+ if (quotedAmount < 50000n) {
80
+ throw new Error('Quoted amount below platform minimum ($0.05)');
81
+ }
82
+ const now = Math.floor(Date.now() / 1000);
83
+ if (quote.expiresAt < now) {
84
+ throw new Error('Quote expired');
85
+ }
86
+ if (Math.abs(now - quote.quotedAt) > 300) {
87
+ throw new Error('Quote timestamp outside 5-minute tolerance');
88
+ }
89
+ return true;
90
+ }
91
+ async uploadToIPFS(quote) {
92
+ if (!this.ipfs) {
93
+ throw new Error('IPFS client not configured');
94
+ }
95
+ const cid = await this.ipfs.add(JSON.stringify(quote));
96
+ await this.ipfs.pin(cid);
97
+ return cid;
98
+ }
99
+ computeHash(quote) {
100
+ const { signature, ...quoteWithoutSig } = quote;
101
+ return (0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)((0, canonicalJson_1.canonicalJsonStringify)(quoteWithoutSig)));
102
+ }
103
+ async signQuote(quote, kernelAddress) {
104
+ const domain = {
105
+ name: 'AGIRAILS',
106
+ version: '1',
107
+ chainId: quote.chainId,
108
+ verifyingContract: kernelAddress
109
+ };
110
+ const justificationHash = this.computeJustificationHash(quote.justification);
111
+ const message = {
112
+ txId: quote.txId,
113
+ provider: quote.provider,
114
+ consumer: quote.consumer,
115
+ quotedAmount: quote.quotedAmount,
116
+ originalAmount: quote.originalAmount,
117
+ maxPrice: quote.maxPrice,
118
+ currency: quote.currency,
119
+ decimals: quote.decimals,
120
+ quotedAt: quote.quotedAt,
121
+ expiresAt: quote.expiresAt,
122
+ justificationHash,
123
+ chainId: quote.chainId,
124
+ nonce: quote.nonce
125
+ };
126
+ if ('signTypedData' in this.signer && typeof this.signer.signTypedData === 'function') {
127
+ const signature = await this.signer.signTypedData(domain, exports.AIP2QuoteTypes, message);
128
+ return signature;
129
+ }
130
+ throw new Error('Signer does not support EIP-712 typed data signing');
131
+ }
132
+ recoverQuoteSigner(quote, kernelAddress) {
133
+ const domain = {
134
+ name: 'AGIRAILS',
135
+ version: '1',
136
+ chainId: quote.chainId,
137
+ verifyingContract: kernelAddress
138
+ };
139
+ const justificationHash = this.computeJustificationHash(quote.justification);
140
+ const message = {
141
+ txId: quote.txId,
142
+ provider: quote.provider,
143
+ consumer: quote.consumer,
144
+ quotedAmount: quote.quotedAmount,
145
+ originalAmount: quote.originalAmount,
146
+ maxPrice: quote.maxPrice,
147
+ currency: quote.currency,
148
+ decimals: quote.decimals,
149
+ quotedAt: quote.quotedAt,
150
+ expiresAt: quote.expiresAt,
151
+ justificationHash,
152
+ chainId: quote.chainId,
153
+ nonce: quote.nonce
154
+ };
155
+ try {
156
+ const recoveredAddress = (0, ethers_1.verifyTypedData)(domain, exports.AIP2QuoteTypes, message, quote.signature);
157
+ return recoveredAddress;
158
+ }
159
+ catch (error) {
160
+ throw new errors_1.SignatureVerificationError(quote.provider, 'unknown');
161
+ }
162
+ }
163
+ computeJustificationHash(justification) {
164
+ if (!justification || Object.keys(justification).length === 0) {
165
+ return '0x0000000000000000000000000000000000000000000000000000000000000000';
166
+ }
167
+ return (0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)((0, canonicalJson_1.canonicalJsonStringify)(justification)));
168
+ }
169
+ validateParams(params) {
170
+ const quotedAmount = BigInt(params.quotedAmount);
171
+ const originalAmount = BigInt(params.originalAmount);
172
+ const maxPrice = BigInt(params.maxPrice);
173
+ if (quotedAmount < originalAmount) {
174
+ throw new Error('quotedAmount must be >= originalAmount');
175
+ }
176
+ if (quotedAmount > maxPrice) {
177
+ throw new Error('quotedAmount must be <= maxPrice');
178
+ }
179
+ if (quotedAmount < 50000n) {
180
+ throw new Error('quotedAmount must be >= $0.05 (50000 base units)');
181
+ }
182
+ if (params.expiresAt) {
183
+ const now = Math.floor(Date.now() / 1000);
184
+ if (params.expiresAt <= now) {
185
+ throw new Error('expiresAt must be in the future');
186
+ }
187
+ if (params.expiresAt > now + 86400) {
188
+ throw new Error('expiresAt cannot be more than 24 hours in future');
189
+ }
190
+ }
191
+ if (!params.provider.startsWith('did:ethr:')) {
192
+ throw new Error('provider must be valid did:ethr format');
193
+ }
194
+ if (!params.consumer.startsWith('did:ethr:')) {
195
+ throw new Error('consumer must be valid did:ethr format');
196
+ }
197
+ if (!/^0x[a-fA-F0-9]{64}$/.test(params.txId)) {
198
+ throw new Error('txId must be valid bytes32 hex string');
199
+ }
200
+ if (!/^0x[a-fA-F0-9]{40}$/.test(params.kernelAddress)) {
201
+ throw new Error('kernelAddress must be valid Ethereum address');
202
+ }
203
+ if (params.chainId !== 84532 && params.chainId !== 8453) {
204
+ throw new Error('chainId must be 84532 (Base Sepolia) or 8453 (Base Mainnet)');
205
+ }
206
+ }
207
+ validateQuoteSchema(quote) {
208
+ if (quote.type !== 'agirails.quote.v1') {
209
+ throw new Error('Invalid message type');
210
+ }
211
+ if (!/^\d+\.\d+\.\d+$/.test(quote.version)) {
212
+ throw new Error('Invalid version format');
213
+ }
214
+ if (!/^0x[a-fA-F0-9]{64}$/.test(quote.txId)) {
215
+ throw new Error('Invalid txId format');
216
+ }
217
+ if (!quote.provider.startsWith('did:ethr:')) {
218
+ throw new Error('Invalid provider DID format');
219
+ }
220
+ if (!quote.consumer.startsWith('did:ethr:')) {
221
+ throw new Error('Invalid consumer DID format');
222
+ }
223
+ if (!/^\d+$/.test(quote.quotedAmount)) {
224
+ throw new Error('Invalid quotedAmount format (must be numeric string)');
225
+ }
226
+ if (!/^\d+$/.test(quote.originalAmount)) {
227
+ throw new Error('Invalid originalAmount format (must be numeric string)');
228
+ }
229
+ if (!/^\d+$/.test(quote.maxPrice)) {
230
+ throw new Error('Invalid maxPrice format (must be numeric string)');
231
+ }
232
+ if (quote.currency !== 'USDC') {
233
+ throw new Error('Only USDC currency is supported');
234
+ }
235
+ if (quote.decimals !== 6) {
236
+ throw new Error('USDC must use 6 decimals');
237
+ }
238
+ if (quote.chainId !== 84532 && quote.chainId !== 8453) {
239
+ throw new Error('Invalid chainId');
240
+ }
241
+ if (!/^0x[a-fA-F0-9]{130}$/.test(quote.signature)) {
242
+ throw new Error('Invalid signature format');
243
+ }
244
+ }
245
+ extractAddressFromDID(did) {
246
+ const parts = did.replace('did:ethr:', '').split(':');
247
+ const address = parts.length === 2 ? parts[1] : parts[0];
248
+ if (!address.startsWith('0x') || address.length !== 42) {
249
+ throw new Error(`Invalid DID format: ${did}`);
250
+ }
251
+ return address;
252
+ }
253
+ }
254
+ exports.QuoteBuilder = QuoteBuilder;
255
+ //# sourceMappingURL=QuoteBuilder.js.map