ox 0.9.10 → 0.9.11
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/CHANGELOG.md +6 -0
- package/_cjs/erc8021/Attribution.js +62 -0
- package/_cjs/erc8021/Attribution.js.map +1 -0
- package/_cjs/erc8021/index.js +5 -0
- package/_cjs/erc8021/index.js.map +1 -0
- package/_cjs/index.docs.js +1 -0
- package/_cjs/index.docs.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/erc8021/Attribution.js +167 -0
- package/_esm/erc8021/Attribution.js.map +1 -0
- package/_esm/erc8021/index.js +35 -0
- package/_esm/erc8021/index.js.map +1 -0
- package/_esm/index.docs.js +1 -0
- package/_esm/index.docs.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/erc8021/Attribution.d.ts +149 -0
- package/_types/erc8021/Attribution.d.ts.map +1 -0
- package/_types/erc8021/index.d.ts +37 -0
- package/_types/erc8021/index.d.ts.map +1 -0
- package/_types/index.docs.d.ts +1 -0
- package/_types/index.docs.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/erc8021/Attribution/package.json +6 -0
- package/erc8021/Attribution.ts +267 -0
- package/erc8021/index.ts +38 -0
- package/erc8021/package.json +6 -0
- package/index.docs.ts +1 -0
- package/package.json +11 -1
- package/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# ox
|
|
2
2
|
|
|
3
|
+
## 0.9.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#126](https://github.com/wevm/ox/pull/126) [`b4572ed`](https://github.com/wevm/ox/commit/b4572ed6feaed7ee1063f8b710d98e928d848016) Thanks [@jxom](https://github.com/jxom)! - Added `ox/erc8021` entrypoint.
|
|
8
|
+
|
|
3
9
|
## 0.9.10
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ercSuffixSize = exports.ercSuffix = void 0;
|
|
4
|
+
exports.getSchemaId = getSchemaId;
|
|
5
|
+
exports.toDataSuffix = toDataSuffix;
|
|
6
|
+
exports.fromData = fromData;
|
|
7
|
+
const Hex = require("../core/Hex.js");
|
|
8
|
+
exports.ercSuffix = '0x80218021802180218021802180218021';
|
|
9
|
+
exports.ercSuffixSize = Hex.size(exports.ercSuffix);
|
|
10
|
+
function getSchemaId(attribution) {
|
|
11
|
+
if ('codeRegistryAddress' in attribution)
|
|
12
|
+
return 1;
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
function toDataSuffix(attribution) {
|
|
16
|
+
const codesHex = Hex.fromString(attribution.codes.join(','));
|
|
17
|
+
const codesLength = Hex.size(codesHex);
|
|
18
|
+
const codesLengthHex = Hex.fromNumber(codesLength, { size: 1 });
|
|
19
|
+
const schemaId = getSchemaId(attribution);
|
|
20
|
+
const schemaIdHex = Hex.fromNumber(schemaId, { size: 1 });
|
|
21
|
+
if (schemaId === 1)
|
|
22
|
+
return Hex.concat(attribution.codeRegistryAddress.toLowerCase(), codesHex, codesLengthHex, schemaIdHex, exports.ercSuffix);
|
|
23
|
+
return Hex.concat(codesHex, codesLengthHex, schemaIdHex, exports.ercSuffix);
|
|
24
|
+
}
|
|
25
|
+
function fromData(data) {
|
|
26
|
+
const minSize = exports.ercSuffixSize + 1 + 1;
|
|
27
|
+
if (Hex.size(data) < minSize)
|
|
28
|
+
return undefined;
|
|
29
|
+
const suffix = Hex.slice(data, -exports.ercSuffixSize);
|
|
30
|
+
if (suffix !== exports.ercSuffix)
|
|
31
|
+
return undefined;
|
|
32
|
+
const schemaIdHex = Hex.slice(data, -exports.ercSuffixSize - 1, -exports.ercSuffixSize);
|
|
33
|
+
const schemaId = Hex.toNumber(schemaIdHex);
|
|
34
|
+
if (schemaId === 0) {
|
|
35
|
+
const codesLengthHex = Hex.slice(data, -exports.ercSuffixSize - 2, -exports.ercSuffixSize - 1);
|
|
36
|
+
const codesLength = Hex.toNumber(codesLengthHex);
|
|
37
|
+
const codesStart = -exports.ercSuffixSize - 2 - codesLength;
|
|
38
|
+
const codesEnd = -exports.ercSuffixSize - 2;
|
|
39
|
+
const codesHex = Hex.slice(data, codesStart, codesEnd);
|
|
40
|
+
const codesString = Hex.toString(codesHex);
|
|
41
|
+
const codes = codesString.length > 0 ? codesString.split(',') : [];
|
|
42
|
+
return { codes, id: 0 };
|
|
43
|
+
}
|
|
44
|
+
if (schemaId === 1) {
|
|
45
|
+
const codesLengthHex = Hex.slice(data, -exports.ercSuffixSize - 2, -exports.ercSuffixSize - 1);
|
|
46
|
+
const codesLength = Hex.toNumber(codesLengthHex);
|
|
47
|
+
const codesStart = -exports.ercSuffixSize - 2 - codesLength;
|
|
48
|
+
const codesEnd = -exports.ercSuffixSize - 2;
|
|
49
|
+
const codesHex = Hex.slice(data, codesStart, codesEnd);
|
|
50
|
+
const codesString = Hex.toString(codesHex);
|
|
51
|
+
const codes = codesString.length > 0 ? codesString.split(',') : [];
|
|
52
|
+
const registryStart = codesStart - 20;
|
|
53
|
+
const codeRegistryAddress = Hex.slice(data, registryStart, codesStart);
|
|
54
|
+
return {
|
|
55
|
+
codes,
|
|
56
|
+
codeRegistryAddress,
|
|
57
|
+
id: 1,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=Attribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Attribution.js","sourceRoot":"","sources":["../../erc8021/Attribution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../erc8021/index.ts"],"names":[],"mappings":";;;AAqCA,kDAA+C"}
|
package/_cjs/index.docs.js
CHANGED
|
@@ -6,4 +6,5 @@ tslib_1.__exportStar(require("./erc4337/index.js"), exports);
|
|
|
6
6
|
tslib_1.__exportStar(require("./erc6492/index.js"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./erc7821/index.js"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./erc8010/index.js"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./erc8021/index.js"), exports);
|
|
9
10
|
//# sourceMappingURL=index.docs.js.map
|
package/_cjs/index.docs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.docs.js","sourceRoot":"","sources":["../index.docs.ts"],"names":[],"mappings":";;;AAGA,qDAA0B;AAC1B,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC"}
|
|
1
|
+
{"version":3,"file":"index.docs.js","sourceRoot":"","sources":["../index.docs.ts"],"names":[],"mappings":";;;AAGA,qDAA0B;AAC1B,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC"}
|
package/_cjs/version.js
CHANGED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as Hex from '../core/Hex.js';
|
|
2
|
+
/**
|
|
3
|
+
* ERC-8021 suffix identifier.
|
|
4
|
+
*/
|
|
5
|
+
export const ercSuffix = '0x80218021802180218021802180218021';
|
|
6
|
+
/**
|
|
7
|
+
* Size of the ERC-8021 suffix (16 bytes).
|
|
8
|
+
*/
|
|
9
|
+
export const ercSuffixSize = /*#__PURE__*/ Hex.size(ercSuffix);
|
|
10
|
+
/**
|
|
11
|
+
* Determines the schema ID for an {@link ox#Attribution.Attribution}.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts twoslash
|
|
15
|
+
* import { Attribution } from 'ox/erc8021'
|
|
16
|
+
*
|
|
17
|
+
* const schemaId = Attribution.getSchemaId({
|
|
18
|
+
* codes: ['baseapp']
|
|
19
|
+
* })
|
|
20
|
+
* // @log: 0
|
|
21
|
+
*
|
|
22
|
+
* const schemaId2 = Attribution.getSchemaId({
|
|
23
|
+
* codes: ['baseapp'],
|
|
24
|
+
* codeRegistryAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
25
|
+
* })
|
|
26
|
+
* // @log: 1
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param attribution - The attribution object.
|
|
30
|
+
* @returns The schema ID (0 for canonical registry, 1 for custom registry).
|
|
31
|
+
*/
|
|
32
|
+
export function getSchemaId(attribution) {
|
|
33
|
+
if ('codeRegistryAddress' in attribution)
|
|
34
|
+
return 1;
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Converts an {@link ox#Attribution.Attribution} to a data suffix that can be appended to transaction calldata.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ### Schema 0 (Canonical Registry)
|
|
42
|
+
*
|
|
43
|
+
* ```ts twoslash
|
|
44
|
+
* import { Attribution } from 'ox/erc8021'
|
|
45
|
+
*
|
|
46
|
+
* const suffix = Attribution.toDataSuffix({
|
|
47
|
+
* codes: ['baseapp', 'morpho']
|
|
48
|
+
* })
|
|
49
|
+
* // @log: '0x626173656170702c6d6f7270686f0e0080218021802180218021802180218021'
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ### Schema 1 (Custom Registry)
|
|
54
|
+
*
|
|
55
|
+
* ```ts twoslash
|
|
56
|
+
* import { Attribution } from 'ox/erc8021'
|
|
57
|
+
*
|
|
58
|
+
* const suffix = Attribution.toDataSuffix({
|
|
59
|
+
* codes: ['baseapp'],
|
|
60
|
+
* codeRegistryAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
61
|
+
* })
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @param attribution - The attribution to convert.
|
|
65
|
+
* @returns The data suffix as a {@link ox#Hex.Hex} value.
|
|
66
|
+
*/
|
|
67
|
+
export function toDataSuffix(attribution) {
|
|
68
|
+
// Encode the codes as ASCII strings separated by commas
|
|
69
|
+
const codesHex = Hex.fromString(attribution.codes.join(','));
|
|
70
|
+
// Get the byte length of the encoded codes
|
|
71
|
+
const codesLength = Hex.size(codesHex);
|
|
72
|
+
// Encode the codes length as 1 byte
|
|
73
|
+
const codesLengthHex = Hex.fromNumber(codesLength, { size: 1 });
|
|
74
|
+
// Determine schema ID
|
|
75
|
+
const schemaId = getSchemaId(attribution);
|
|
76
|
+
const schemaIdHex = Hex.fromNumber(schemaId, { size: 1 });
|
|
77
|
+
// Build the suffix based on schema
|
|
78
|
+
if (schemaId === 1)
|
|
79
|
+
// Schema 1: codeRegistryAddress ∥ codes ∥ codesLength ∥ schemaId ∥ ercSuffix
|
|
80
|
+
return Hex.concat(attribution.codeRegistryAddress.toLowerCase(), codesHex, codesLengthHex, schemaIdHex, ercSuffix);
|
|
81
|
+
// Schema 0: codes ∥ codesLength ∥ schemaId ∥ ercSuffix
|
|
82
|
+
return Hex.concat(codesHex, codesLengthHex, schemaIdHex, ercSuffix);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Extracts an {@link ox#Attribution.Attribution} from transaction calldata.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ### Schema 0 (Canonical Registry)
|
|
89
|
+
*
|
|
90
|
+
* ```ts twoslash
|
|
91
|
+
* import { Attribution } from 'ox/erc8021'
|
|
92
|
+
*
|
|
93
|
+
* const attribution = Attribution.fromData(
|
|
94
|
+
* '0xdddddddd62617365617070070080218021802180218021802180218021'
|
|
95
|
+
* )
|
|
96
|
+
* // @log: { codes: ['baseapp'], id: 0 }
|
|
97
|
+
* ```
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ### Schema 1 (Custom Registry)
|
|
101
|
+
*
|
|
102
|
+
* ```ts twoslash
|
|
103
|
+
* import { Attribution } from 'ox/erc8021'
|
|
104
|
+
*
|
|
105
|
+
* const attribution = Attribution.fromData(
|
|
106
|
+
* '0xdddddddd626173656170702c6d6f7270686f0ecccccccccccccccccccccccccccccccccccccccc0180218021802180218021802180218021'
|
|
107
|
+
* )
|
|
108
|
+
* // @log: {
|
|
109
|
+
* // codes: ['baseapp', 'morpho'],
|
|
110
|
+
* // codeRegistryAddress: '0xcccccccccccccccccccccccccccccccccccccccc',
|
|
111
|
+
* // id: 1
|
|
112
|
+
* // }
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @param data - The transaction calldata containing the attribution suffix.
|
|
116
|
+
* @returns The extracted attribution, or undefined if no valid attribution is found.
|
|
117
|
+
*/
|
|
118
|
+
export function fromData(data) {
|
|
119
|
+
// Check minimum length: ERC suffix (16 bytes) + schema ID (1 byte) + length (1 byte) = 18 bytes
|
|
120
|
+
const minSize = ercSuffixSize + 1 + 1;
|
|
121
|
+
if (Hex.size(data) < minSize)
|
|
122
|
+
return undefined;
|
|
123
|
+
// Verify ERC suffix is present at the end
|
|
124
|
+
const suffix = Hex.slice(data, -ercSuffixSize);
|
|
125
|
+
if (suffix !== ercSuffix)
|
|
126
|
+
return undefined;
|
|
127
|
+
// Extract schema ID (1 byte before the ERC suffix)
|
|
128
|
+
const schemaIdHex = Hex.slice(data, -ercSuffixSize - 1, -ercSuffixSize);
|
|
129
|
+
const schemaId = Hex.toNumber(schemaIdHex);
|
|
130
|
+
// Schema 0: Canonical registry
|
|
131
|
+
if (schemaId === 0) {
|
|
132
|
+
// Extract codes length (1 byte before schema ID)
|
|
133
|
+
const codesLengthHex = Hex.slice(data, -ercSuffixSize - 2, -ercSuffixSize - 1);
|
|
134
|
+
const codesLength = Hex.toNumber(codesLengthHex);
|
|
135
|
+
// Extract codes
|
|
136
|
+
const codesStart = -ercSuffixSize - 2 - codesLength;
|
|
137
|
+
const codesEnd = -ercSuffixSize - 2;
|
|
138
|
+
const codesHex = Hex.slice(data, codesStart, codesEnd);
|
|
139
|
+
const codesString = Hex.toString(codesHex);
|
|
140
|
+
const codes = codesString.length > 0 ? codesString.split(',') : [];
|
|
141
|
+
return { codes, id: 0 };
|
|
142
|
+
}
|
|
143
|
+
// Schema 1: Custom registry
|
|
144
|
+
// Format: codeRegistryAddress (20 bytes) ∥ codes ∥ codesLength (1 byte) ∥ schemaId (1 byte) ∥ ercSuffix
|
|
145
|
+
if (schemaId === 1) {
|
|
146
|
+
// Extract codes length (1 byte before schema ID)
|
|
147
|
+
const codesLengthHex = Hex.slice(data, -ercSuffixSize - 2, -ercSuffixSize - 1);
|
|
148
|
+
const codesLength = Hex.toNumber(codesLengthHex);
|
|
149
|
+
// Extract codes
|
|
150
|
+
const codesStart = -ercSuffixSize - 2 - codesLength;
|
|
151
|
+
const codesEnd = -ercSuffixSize - 2;
|
|
152
|
+
const codesHex = Hex.slice(data, codesStart, codesEnd);
|
|
153
|
+
const codesString = Hex.toString(codesHex);
|
|
154
|
+
const codes = codesString.length > 0 ? codesString.split(',') : [];
|
|
155
|
+
// Extract registry address (20 bytes before codes)
|
|
156
|
+
const registryStart = codesStart - 20;
|
|
157
|
+
const codeRegistryAddress = Hex.slice(data, registryStart, codesStart);
|
|
158
|
+
return {
|
|
159
|
+
codes,
|
|
160
|
+
codeRegistryAddress,
|
|
161
|
+
id: 1,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
// Unknown schema ID
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=Attribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Attribution.js","sourceRoot":"","sources":["../../erc8021/Attribution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for working with [ERC-8021 Transaction Attribution](https://eip.tools/eip/8021).
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ### Converting an Attribution to Data Suffix
|
|
6
|
+
*
|
|
7
|
+
* ```ts twoslash
|
|
8
|
+
* import { Attribution } from 'ox/erc8021'
|
|
9
|
+
*
|
|
10
|
+
* const dataSuffix1 = Attribution.toDataSuffix({
|
|
11
|
+
* codes: ['baseapp']
|
|
12
|
+
* })
|
|
13
|
+
*
|
|
14
|
+
* const dataSuffix2 = Attribution.toDataSuffix({
|
|
15
|
+
* codes: ['baseapp', 'morpho'],
|
|
16
|
+
* codeRegistryAddress: '0x...'
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ### Extracting an Attribution from Calldata
|
|
22
|
+
*
|
|
23
|
+
* ```ts twoslash
|
|
24
|
+
* import { Attribution } from 'ox/erc8021'
|
|
25
|
+
*
|
|
26
|
+
* const attribution = Attribution.fromData('0x...')
|
|
27
|
+
*
|
|
28
|
+
* console.log(attribution)
|
|
29
|
+
* // @log: { codes: ['baseapp', 'morpho'], codeRegistryAddress: '0x...' }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @category ERC-8021
|
|
33
|
+
*/
|
|
34
|
+
export * as Attribution from './Attribution.js';
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../erc8021/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA"}
|
package/_esm/index.docs.js
CHANGED
package/_esm/index.docs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.docs.js","sourceRoot":"","sources":["../index.docs.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,2FAA2F;AAC3F,gDAAgD;AAChD,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.docs.js","sourceRoot":"","sources":["../index.docs.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,2FAA2F;AAC3F,gDAAgD;AAChD,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA"}
|
package/_esm/version.js
CHANGED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type * as Address from '../core/Address.js';
|
|
2
|
+
import type * as Errors from '../core/Errors.js';
|
|
3
|
+
import * as Hex from '../core/Hex.js';
|
|
4
|
+
import type { OneOf } from '../core/internal/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* ERC-8021 Transaction Attribution.
|
|
7
|
+
*
|
|
8
|
+
* Represents attribution metadata that can be appended to transaction calldata
|
|
9
|
+
* to track entities involved in facilitating a transaction.
|
|
10
|
+
*/
|
|
11
|
+
export type Attribution = OneOf<AttributionSchemaId0 | AttributionSchemaId1>;
|
|
12
|
+
/**
|
|
13
|
+
* Schema 0: Canonical Registry Attribution.
|
|
14
|
+
*
|
|
15
|
+
* Uses the canonical attribution code registry for resolving entity identities.
|
|
16
|
+
*/
|
|
17
|
+
export type AttributionSchemaId0 = {
|
|
18
|
+
/** Attribution codes identifying entities involved in the transaction. */
|
|
19
|
+
codes: readonly string[];
|
|
20
|
+
/** Schema identifier (0 for canonical registry). */
|
|
21
|
+
id?: 0 | undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Schema 1: Custom Registry Attribution.
|
|
25
|
+
*
|
|
26
|
+
* Uses a custom registry contract for resolving attribution codes.
|
|
27
|
+
*/
|
|
28
|
+
export type AttributionSchemaId1 = {
|
|
29
|
+
/** Attribution codes identifying entities involved in the transaction. */
|
|
30
|
+
codes: readonly string[];
|
|
31
|
+
/** Address of the custom code registry contract. */
|
|
32
|
+
codeRegistryAddress: Address.Address;
|
|
33
|
+
/** Schema identifier (1 for custom registry). */
|
|
34
|
+
id?: 1 | undefined;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Attribution schema identifier.
|
|
38
|
+
*
|
|
39
|
+
* - `0`: Canonical registry
|
|
40
|
+
* - `1`: Custom registry
|
|
41
|
+
*/
|
|
42
|
+
export type SchemaId = NonNullable<AttributionSchemaId0['id'] | AttributionSchemaId1['id']>;
|
|
43
|
+
/**
|
|
44
|
+
* ERC-8021 suffix identifier.
|
|
45
|
+
*/
|
|
46
|
+
export declare const ercSuffix: "0x80218021802180218021802180218021";
|
|
47
|
+
/**
|
|
48
|
+
* Size of the ERC-8021 suffix (16 bytes).
|
|
49
|
+
*/
|
|
50
|
+
export declare const ercSuffixSize: number;
|
|
51
|
+
/**
|
|
52
|
+
* Determines the schema ID for an {@link ox#Attribution.Attribution}.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts twoslash
|
|
56
|
+
* import { Attribution } from 'ox/erc8021'
|
|
57
|
+
*
|
|
58
|
+
* const schemaId = Attribution.getSchemaId({
|
|
59
|
+
* codes: ['baseapp']
|
|
60
|
+
* })
|
|
61
|
+
* // @log: 0
|
|
62
|
+
*
|
|
63
|
+
* const schemaId2 = Attribution.getSchemaId({
|
|
64
|
+
* codes: ['baseapp'],
|
|
65
|
+
* codeRegistryAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
66
|
+
* })
|
|
67
|
+
* // @log: 1
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @param attribution - The attribution object.
|
|
71
|
+
* @returns The schema ID (0 for canonical registry, 1 for custom registry).
|
|
72
|
+
*/
|
|
73
|
+
export declare function getSchemaId(attribution: Attribution): SchemaId;
|
|
74
|
+
export declare namespace getSchemaId {
|
|
75
|
+
type ErrorType = Errors.GlobalErrorType;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Converts an {@link ox#Attribution.Attribution} to a data suffix that can be appended to transaction calldata.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ### Schema 0 (Canonical Registry)
|
|
82
|
+
*
|
|
83
|
+
* ```ts twoslash
|
|
84
|
+
* import { Attribution } from 'ox/erc8021'
|
|
85
|
+
*
|
|
86
|
+
* const suffix = Attribution.toDataSuffix({
|
|
87
|
+
* codes: ['baseapp', 'morpho']
|
|
88
|
+
* })
|
|
89
|
+
* // @log: '0x626173656170702c6d6f7270686f0e0080218021802180218021802180218021'
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ### Schema 1 (Custom Registry)
|
|
94
|
+
*
|
|
95
|
+
* ```ts twoslash
|
|
96
|
+
* import { Attribution } from 'ox/erc8021'
|
|
97
|
+
*
|
|
98
|
+
* const suffix = Attribution.toDataSuffix({
|
|
99
|
+
* codes: ['baseapp'],
|
|
100
|
+
* codeRegistryAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
101
|
+
* })
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @param attribution - The attribution to convert.
|
|
105
|
+
* @returns The data suffix as a {@link ox#Hex.Hex} value.
|
|
106
|
+
*/
|
|
107
|
+
export declare function toDataSuffix(attribution: Attribution): Hex.Hex;
|
|
108
|
+
export declare namespace toDataSuffix {
|
|
109
|
+
type ErrorType = getSchemaId.ErrorType | Hex.concat.ErrorType | Hex.fromString.ErrorType | Hex.fromNumber.ErrorType | Hex.size.ErrorType | Errors.GlobalErrorType;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Extracts an {@link ox#Attribution.Attribution} from transaction calldata.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ### Schema 0 (Canonical Registry)
|
|
116
|
+
*
|
|
117
|
+
* ```ts twoslash
|
|
118
|
+
* import { Attribution } from 'ox/erc8021'
|
|
119
|
+
*
|
|
120
|
+
* const attribution = Attribution.fromData(
|
|
121
|
+
* '0xdddddddd62617365617070070080218021802180218021802180218021'
|
|
122
|
+
* )
|
|
123
|
+
* // @log: { codes: ['baseapp'], id: 0 }
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ### Schema 1 (Custom Registry)
|
|
128
|
+
*
|
|
129
|
+
* ```ts twoslash
|
|
130
|
+
* import { Attribution } from 'ox/erc8021'
|
|
131
|
+
*
|
|
132
|
+
* const attribution = Attribution.fromData(
|
|
133
|
+
* '0xdddddddd626173656170702c6d6f7270686f0ecccccccccccccccccccccccccccccccccccccccc0180218021802180218021802180218021'
|
|
134
|
+
* )
|
|
135
|
+
* // @log: {
|
|
136
|
+
* // codes: ['baseapp', 'morpho'],
|
|
137
|
+
* // codeRegistryAddress: '0xcccccccccccccccccccccccccccccccccccccccc',
|
|
138
|
+
* // id: 1
|
|
139
|
+
* // }
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @param data - The transaction calldata containing the attribution suffix.
|
|
143
|
+
* @returns The extracted attribution, or undefined if no valid attribution is found.
|
|
144
|
+
*/
|
|
145
|
+
export declare function fromData(data: Hex.Hex): Attribution | undefined;
|
|
146
|
+
export declare namespace fromData {
|
|
147
|
+
type ErrorType = Hex.slice.ErrorType | Hex.toNumber.ErrorType | Hex.toString.ErrorType | Hex.size.ErrorType | Errors.GlobalErrorType;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=Attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Attribution.d.ts","sourceRoot":"","sources":["../../erc8021/Attribution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,CAAA;AAE5E;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,0EAA0E;IAC1E,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,oDAAoD;IACpD,EAAE,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;CACnB,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,0EAA0E;IAC1E,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,oDAAoD;IACpD,mBAAmB,EAAE,OAAO,CAAC,OAAO,CAAA;IACpC,iDAAiD;IACjD,EAAE,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;CACnB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,CAChC,oBAAoB,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CACxD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,sCAAgD,CAAA;AAEtE;;GAEG;AACH,eAAO,MAAM,aAAa,QAAoC,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,WAAW,GAAG,QAAQ,CAG9D;AAED,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC;IACnC,KAAK,SAAS,GAAG,MAAM,CAAC,eAAe,CAAA;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,GAAG,CAAC,GAAG,CA2B9D;AAED,MAAM,CAAC,OAAO,WAAW,YAAY,CAAC;IACpC,KAAK,SAAS,GACV,WAAW,CAAC,SAAS,GACrB,GAAG,CAAC,MAAM,CAAC,SAAS,GACpB,GAAG,CAAC,UAAU,CAAC,SAAS,GACxB,GAAG,CAAC,UAAU,CAAC,SAAS,GACxB,GAAG,CAAC,IAAI,CAAC,SAAS,GAClB,MAAM,CAAC,eAAe,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,WAAW,GAAG,SAAS,CAgE/D;AAED,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,KAAK,SAAS,GACV,GAAG,CAAC,KAAK,CAAC,SAAS,GACnB,GAAG,CAAC,QAAQ,CAAC,SAAS,GACtB,GAAG,CAAC,QAAQ,CAAC,SAAS,GACtB,GAAG,CAAC,IAAI,CAAC,SAAS,GAClB,MAAM,CAAC,eAAe,CAAA;CAC3B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** @entrypointCategory ERCs */
|
|
2
|
+
export type {};
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for working with [ERC-8021 Transaction Attribution](https://eip.tools/eip/8021).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ### Converting an Attribution to Data Suffix
|
|
8
|
+
*
|
|
9
|
+
* ```ts twoslash
|
|
10
|
+
* import { Attribution } from 'ox/erc8021'
|
|
11
|
+
*
|
|
12
|
+
* const dataSuffix1 = Attribution.toDataSuffix({
|
|
13
|
+
* codes: ['baseapp']
|
|
14
|
+
* })
|
|
15
|
+
*
|
|
16
|
+
* const dataSuffix2 = Attribution.toDataSuffix({
|
|
17
|
+
* codes: ['baseapp', 'morpho'],
|
|
18
|
+
* codeRegistryAddress: '0x...'
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ### Extracting an Attribution from Calldata
|
|
24
|
+
*
|
|
25
|
+
* ```ts twoslash
|
|
26
|
+
* import { Attribution } from 'ox/erc8021'
|
|
27
|
+
*
|
|
28
|
+
* const attribution = Attribution.fromData('0x...')
|
|
29
|
+
*
|
|
30
|
+
* console.log(attribution)
|
|
31
|
+
* // @log: { codes: ['baseapp', 'morpho'], codeRegistryAddress: '0x...' }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @category ERC-8021
|
|
35
|
+
*/
|
|
36
|
+
export * as Attribution from './Attribution.js';
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../erc8021/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA"}
|
package/_types/index.docs.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.docs.d.ts","sourceRoot":"","sources":["../index.docs.ts"],"names":[],"mappings":"AACA,2FAA2F;AAE3F,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.docs.d.ts","sourceRoot":"","sources":["../index.docs.ts"],"names":[],"mappings":"AACA,2FAA2F;AAE3F,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA"}
|
package/_types/version.d.ts
CHANGED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import type * as Address from '../core/Address.js'
|
|
2
|
+
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as Hex from '../core/Hex.js'
|
|
4
|
+
import type { OneOf } from '../core/internal/types.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ERC-8021 Transaction Attribution.
|
|
8
|
+
*
|
|
9
|
+
* Represents attribution metadata that can be appended to transaction calldata
|
|
10
|
+
* to track entities involved in facilitating a transaction.
|
|
11
|
+
*/
|
|
12
|
+
export type Attribution = OneOf<AttributionSchemaId0 | AttributionSchemaId1>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Schema 0: Canonical Registry Attribution.
|
|
16
|
+
*
|
|
17
|
+
* Uses the canonical attribution code registry for resolving entity identities.
|
|
18
|
+
*/
|
|
19
|
+
export type AttributionSchemaId0 = {
|
|
20
|
+
/** Attribution codes identifying entities involved in the transaction. */
|
|
21
|
+
codes: readonly string[]
|
|
22
|
+
/** Schema identifier (0 for canonical registry). */
|
|
23
|
+
id?: 0 | undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Schema 1: Custom Registry Attribution.
|
|
28
|
+
*
|
|
29
|
+
* Uses a custom registry contract for resolving attribution codes.
|
|
30
|
+
*/
|
|
31
|
+
export type AttributionSchemaId1 = {
|
|
32
|
+
/** Attribution codes identifying entities involved in the transaction. */
|
|
33
|
+
codes: readonly string[]
|
|
34
|
+
/** Address of the custom code registry contract. */
|
|
35
|
+
codeRegistryAddress: Address.Address
|
|
36
|
+
/** Schema identifier (1 for custom registry). */
|
|
37
|
+
id?: 1 | undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Attribution schema identifier.
|
|
42
|
+
*
|
|
43
|
+
* - `0`: Canonical registry
|
|
44
|
+
* - `1`: Custom registry
|
|
45
|
+
*/
|
|
46
|
+
export type SchemaId = NonNullable<
|
|
47
|
+
AttributionSchemaId0['id'] | AttributionSchemaId1['id']
|
|
48
|
+
>
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* ERC-8021 suffix identifier.
|
|
52
|
+
*/
|
|
53
|
+
export const ercSuffix = '0x80218021802180218021802180218021' as const
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Size of the ERC-8021 suffix (16 bytes).
|
|
57
|
+
*/
|
|
58
|
+
export const ercSuffixSize = /*#__PURE__*/ Hex.size(ercSuffix)
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Determines the schema ID for an {@link ox#Attribution.Attribution}.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts twoslash
|
|
65
|
+
* import { Attribution } from 'ox/erc8021'
|
|
66
|
+
*
|
|
67
|
+
* const schemaId = Attribution.getSchemaId({
|
|
68
|
+
* codes: ['baseapp']
|
|
69
|
+
* })
|
|
70
|
+
* // @log: 0
|
|
71
|
+
*
|
|
72
|
+
* const schemaId2 = Attribution.getSchemaId({
|
|
73
|
+
* codes: ['baseapp'],
|
|
74
|
+
* codeRegistryAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
75
|
+
* })
|
|
76
|
+
* // @log: 1
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @param attribution - The attribution object.
|
|
80
|
+
* @returns The schema ID (0 for canonical registry, 1 for custom registry).
|
|
81
|
+
*/
|
|
82
|
+
export function getSchemaId(attribution: Attribution): SchemaId {
|
|
83
|
+
if ('codeRegistryAddress' in attribution) return 1
|
|
84
|
+
return 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export declare namespace getSchemaId {
|
|
88
|
+
type ErrorType = Errors.GlobalErrorType
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Converts an {@link ox#Attribution.Attribution} to a data suffix that can be appended to transaction calldata.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ### Schema 0 (Canonical Registry)
|
|
96
|
+
*
|
|
97
|
+
* ```ts twoslash
|
|
98
|
+
* import { Attribution } from 'ox/erc8021'
|
|
99
|
+
*
|
|
100
|
+
* const suffix = Attribution.toDataSuffix({
|
|
101
|
+
* codes: ['baseapp', 'morpho']
|
|
102
|
+
* })
|
|
103
|
+
* // @log: '0x626173656170702c6d6f7270686f0e0080218021802180218021802180218021'
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ### Schema 1 (Custom Registry)
|
|
108
|
+
*
|
|
109
|
+
* ```ts twoslash
|
|
110
|
+
* import { Attribution } from 'ox/erc8021'
|
|
111
|
+
*
|
|
112
|
+
* const suffix = Attribution.toDataSuffix({
|
|
113
|
+
* codes: ['baseapp'],
|
|
114
|
+
* codeRegistryAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
115
|
+
* })
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @param attribution - The attribution to convert.
|
|
119
|
+
* @returns The data suffix as a {@link ox#Hex.Hex} value.
|
|
120
|
+
*/
|
|
121
|
+
export function toDataSuffix(attribution: Attribution): Hex.Hex {
|
|
122
|
+
// Encode the codes as ASCII strings separated by commas
|
|
123
|
+
const codesHex = Hex.fromString(attribution.codes.join(','))
|
|
124
|
+
|
|
125
|
+
// Get the byte length of the encoded codes
|
|
126
|
+
const codesLength = Hex.size(codesHex)
|
|
127
|
+
|
|
128
|
+
// Encode the codes length as 1 byte
|
|
129
|
+
const codesLengthHex = Hex.fromNumber(codesLength, { size: 1 })
|
|
130
|
+
|
|
131
|
+
// Determine schema ID
|
|
132
|
+
const schemaId = getSchemaId(attribution)
|
|
133
|
+
const schemaIdHex = Hex.fromNumber(schemaId, { size: 1 })
|
|
134
|
+
|
|
135
|
+
// Build the suffix based on schema
|
|
136
|
+
if (schemaId === 1)
|
|
137
|
+
// Schema 1: codeRegistryAddress ∥ codes ∥ codesLength ∥ schemaId ∥ ercSuffix
|
|
138
|
+
return Hex.concat(
|
|
139
|
+
attribution.codeRegistryAddress!.toLowerCase() as Address.Address,
|
|
140
|
+
codesHex,
|
|
141
|
+
codesLengthHex,
|
|
142
|
+
schemaIdHex,
|
|
143
|
+
ercSuffix,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
// Schema 0: codes ∥ codesLength ∥ schemaId ∥ ercSuffix
|
|
147
|
+
return Hex.concat(codesHex, codesLengthHex, schemaIdHex, ercSuffix)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export declare namespace toDataSuffix {
|
|
151
|
+
type ErrorType =
|
|
152
|
+
| getSchemaId.ErrorType
|
|
153
|
+
| Hex.concat.ErrorType
|
|
154
|
+
| Hex.fromString.ErrorType
|
|
155
|
+
| Hex.fromNumber.ErrorType
|
|
156
|
+
| Hex.size.ErrorType
|
|
157
|
+
| Errors.GlobalErrorType
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Extracts an {@link ox#Attribution.Attribution} from transaction calldata.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ### Schema 0 (Canonical Registry)
|
|
165
|
+
*
|
|
166
|
+
* ```ts twoslash
|
|
167
|
+
* import { Attribution } from 'ox/erc8021'
|
|
168
|
+
*
|
|
169
|
+
* const attribution = Attribution.fromData(
|
|
170
|
+
* '0xdddddddd62617365617070070080218021802180218021802180218021'
|
|
171
|
+
* )
|
|
172
|
+
* // @log: { codes: ['baseapp'], id: 0 }
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ### Schema 1 (Custom Registry)
|
|
177
|
+
*
|
|
178
|
+
* ```ts twoslash
|
|
179
|
+
* import { Attribution } from 'ox/erc8021'
|
|
180
|
+
*
|
|
181
|
+
* const attribution = Attribution.fromData(
|
|
182
|
+
* '0xdddddddd626173656170702c6d6f7270686f0ecccccccccccccccccccccccccccccccccccccccc0180218021802180218021802180218021'
|
|
183
|
+
* )
|
|
184
|
+
* // @log: {
|
|
185
|
+
* // codes: ['baseapp', 'morpho'],
|
|
186
|
+
* // codeRegistryAddress: '0xcccccccccccccccccccccccccccccccccccccccc',
|
|
187
|
+
* // id: 1
|
|
188
|
+
* // }
|
|
189
|
+
* ```
|
|
190
|
+
*
|
|
191
|
+
* @param data - The transaction calldata containing the attribution suffix.
|
|
192
|
+
* @returns The extracted attribution, or undefined if no valid attribution is found.
|
|
193
|
+
*/
|
|
194
|
+
export function fromData(data: Hex.Hex): Attribution | undefined {
|
|
195
|
+
// Check minimum length: ERC suffix (16 bytes) + schema ID (1 byte) + length (1 byte) = 18 bytes
|
|
196
|
+
const minSize = ercSuffixSize + 1 + 1
|
|
197
|
+
if (Hex.size(data) < minSize) return undefined
|
|
198
|
+
|
|
199
|
+
// Verify ERC suffix is present at the end
|
|
200
|
+
const suffix = Hex.slice(data, -ercSuffixSize)
|
|
201
|
+
if (suffix !== ercSuffix) return undefined
|
|
202
|
+
|
|
203
|
+
// Extract schema ID (1 byte before the ERC suffix)
|
|
204
|
+
const schemaIdHex = Hex.slice(data, -ercSuffixSize - 1, -ercSuffixSize)
|
|
205
|
+
const schemaId = Hex.toNumber(schemaIdHex)
|
|
206
|
+
|
|
207
|
+
// Schema 0: Canonical registry
|
|
208
|
+
if (schemaId === 0) {
|
|
209
|
+
// Extract codes length (1 byte before schema ID)
|
|
210
|
+
const codesLengthHex = Hex.slice(
|
|
211
|
+
data,
|
|
212
|
+
-ercSuffixSize - 2,
|
|
213
|
+
-ercSuffixSize - 1,
|
|
214
|
+
)
|
|
215
|
+
const codesLength = Hex.toNumber(codesLengthHex)
|
|
216
|
+
|
|
217
|
+
// Extract codes
|
|
218
|
+
const codesStart = -ercSuffixSize - 2 - codesLength
|
|
219
|
+
const codesEnd = -ercSuffixSize - 2
|
|
220
|
+
const codesHex = Hex.slice(data, codesStart, codesEnd)
|
|
221
|
+
const codesString = Hex.toString(codesHex)
|
|
222
|
+
const codes = codesString.length > 0 ? codesString.split(',') : []
|
|
223
|
+
|
|
224
|
+
return { codes, id: 0 }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Schema 1: Custom registry
|
|
228
|
+
// Format: codeRegistryAddress (20 bytes) ∥ codes ∥ codesLength (1 byte) ∥ schemaId (1 byte) ∥ ercSuffix
|
|
229
|
+
if (schemaId === 1) {
|
|
230
|
+
// Extract codes length (1 byte before schema ID)
|
|
231
|
+
const codesLengthHex = Hex.slice(
|
|
232
|
+
data,
|
|
233
|
+
-ercSuffixSize - 2,
|
|
234
|
+
-ercSuffixSize - 1,
|
|
235
|
+
)
|
|
236
|
+
const codesLength = Hex.toNumber(codesLengthHex)
|
|
237
|
+
|
|
238
|
+
// Extract codes
|
|
239
|
+
const codesStart = -ercSuffixSize - 2 - codesLength
|
|
240
|
+
const codesEnd = -ercSuffixSize - 2
|
|
241
|
+
const codesHex = Hex.slice(data, codesStart, codesEnd)
|
|
242
|
+
const codesString = Hex.toString(codesHex)
|
|
243
|
+
const codes = codesString.length > 0 ? codesString.split(',') : []
|
|
244
|
+
|
|
245
|
+
// Extract registry address (20 bytes before codes)
|
|
246
|
+
const registryStart = codesStart - 20
|
|
247
|
+
const codeRegistryAddress = Hex.slice(data, registryStart, codesStart)
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
codes,
|
|
251
|
+
codeRegistryAddress,
|
|
252
|
+
id: 1,
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Unknown schema ID
|
|
257
|
+
return undefined
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export declare namespace fromData {
|
|
261
|
+
type ErrorType =
|
|
262
|
+
| Hex.slice.ErrorType
|
|
263
|
+
| Hex.toNumber.ErrorType
|
|
264
|
+
| Hex.toString.ErrorType
|
|
265
|
+
| Hex.size.ErrorType
|
|
266
|
+
| Errors.GlobalErrorType
|
|
267
|
+
}
|
package/erc8021/index.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @entrypointCategory ERCs */
|
|
2
|
+
// biome-ignore lint/complexity/noUselessEmptyExport: tsdoc
|
|
3
|
+
export type {}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Utility functions for working with [ERC-8021 Transaction Attribution](https://eip.tools/eip/8021).
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ### Converting an Attribution to Data Suffix
|
|
10
|
+
*
|
|
11
|
+
* ```ts twoslash
|
|
12
|
+
* import { Attribution } from 'ox/erc8021'
|
|
13
|
+
*
|
|
14
|
+
* const dataSuffix1 = Attribution.toDataSuffix({
|
|
15
|
+
* codes: ['baseapp']
|
|
16
|
+
* })
|
|
17
|
+
*
|
|
18
|
+
* const dataSuffix2 = Attribution.toDataSuffix({
|
|
19
|
+
* codes: ['baseapp', 'morpho'],
|
|
20
|
+
* codeRegistryAddress: '0x...'
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ### Extracting an Attribution from Calldata
|
|
26
|
+
*
|
|
27
|
+
* ```ts twoslash
|
|
28
|
+
* import { Attribution } from 'ox/erc8021'
|
|
29
|
+
*
|
|
30
|
+
* const attribution = Attribution.fromData('0x...')
|
|
31
|
+
*
|
|
32
|
+
* console.log(attribution)
|
|
33
|
+
* // @log: { codes: ['baseapp', 'morpho'], codeRegistryAddress: '0x...' }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @category ERC-8021
|
|
37
|
+
*/
|
|
38
|
+
export * as Attribution from './Attribution.js'
|
package/index.docs.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ox",
|
|
3
3
|
"description": "Ethereum Standard Library",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.11",
|
|
5
5
|
"main": "./_cjs/index.js",
|
|
6
6
|
"module": "./_esm/index.js",
|
|
7
7
|
"types": "./_types/index.d.ts",
|
|
@@ -453,6 +453,16 @@
|
|
|
453
453
|
"import": "./_esm/erc8010/index.js",
|
|
454
454
|
"default": "./_cjs/erc8010/index.js"
|
|
455
455
|
},
|
|
456
|
+
"./erc8021/Attribution": {
|
|
457
|
+
"types": "./_types/erc8021/Attribution.d.ts",
|
|
458
|
+
"import": "./_esm/erc8021/Attribution.js",
|
|
459
|
+
"default": "./_cjs/erc8021/Attribution.js"
|
|
460
|
+
},
|
|
461
|
+
"./erc8021": {
|
|
462
|
+
"types": "./_types/erc8021/index.d.ts",
|
|
463
|
+
"import": "./_esm/erc8021/index.js",
|
|
464
|
+
"default": "./_cjs/erc8021/index.js"
|
|
465
|
+
},
|
|
456
466
|
"./index.docs": {
|
|
457
467
|
"types": "./_types/index.docs.d.ts",
|
|
458
468
|
"import": "./_esm/index.docs.js",
|
package/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal */
|
|
2
|
-
export const version = '0.9.
|
|
2
|
+
export const version = '0.9.11'
|