ox 0.14.22 → 0.14.24

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # ox
2
2
 
3
+ ## 0.14.24
4
+
5
+ ### Patch Changes
6
+
7
+ - [#254](https://github.com/wevm/ox/pull/254) [`d837628`](https://github.com/wevm/ox/commit/d8376284988f6c2b56d9cb18ac2b677465f3b835) Thanks [@jxom](https://github.com/jxom)! - Added `ChannelDescriptor.from` for normalizing TIP-20 channel reserve descriptors.
8
+
9
+ ## 0.14.23
10
+
11
+ ### Patch Changes
12
+
13
+ - [#252](https://github.com/wevm/ox/pull/252) [`19cd833`](https://github.com/wevm/ox/commit/19cd83342bfddc682a8897f0cb5c383e8954586d) Thanks [@jxom](https://github.com/jxom)! - Added TIP-20 channel reserve constants, channel id computation, and voucher signing helpers.
14
+
3
15
  ## 0.14.22
4
16
 
5
17
  ### Patch Changes
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.voucherTypehash = exports.closeGracePeriod = exports.address = void 0;
4
+ exports.computeId = computeId;
5
+ exports.domainSeparator = domainSeparator;
6
+ exports.getVoucherSignPayload = getVoucherSignPayload;
7
+ const AbiParameters = require("../core/AbiParameters.js");
8
+ const Hash = require("../core/Hash.js");
9
+ const Hex = require("../core/Hex.js");
10
+ const ChannelDescriptor = require("./ChannelDescriptor.js");
11
+ const channelIdParameters = AbiParameters.from('address, address, address, address, bytes32, address, bytes32, address, uint256');
12
+ const domainSeparatorParameters = AbiParameters.from('bytes32, bytes32, bytes32, uint256, address');
13
+ const voucherHashParameters = AbiParameters.from('bytes32, bytes32, uint96');
14
+ const eip712DomainTypehash = Hash.keccak256(Hex.fromString('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'));
15
+ const nameHash = Hash.keccak256(Hex.fromString('TIP20 Channel Reserve'));
16
+ const versionHash = Hash.keccak256(Hex.fromString('1'));
17
+ exports.address = '0x4d50500000000000000000000000000000000000';
18
+ exports.closeGracePeriod = 900n;
19
+ exports.voucherTypehash = Hash.keccak256(Hex.fromString('Voucher(bytes32 channelId,uint96 cumulativeAmount)'));
20
+ function computeId(value) {
21
+ const descriptor = ChannelDescriptor.from(value);
22
+ return Hash.keccak256(AbiParameters.encode(channelIdParameters, [
23
+ descriptor.payer,
24
+ descriptor.payee,
25
+ descriptor.operator,
26
+ descriptor.token,
27
+ descriptor.salt,
28
+ descriptor.authorizedSigner,
29
+ descriptor.expiringNonceHash,
30
+ exports.address,
31
+ BigInt(value.chainId),
32
+ ]));
33
+ }
34
+ function domainSeparator(value) {
35
+ return Hash.keccak256(AbiParameters.encode(domainSeparatorParameters, [
36
+ eip712DomainTypehash,
37
+ nameHash,
38
+ versionHash,
39
+ BigInt(value.chainId),
40
+ exports.address,
41
+ ]));
42
+ }
43
+ function getVoucherSignPayload(value) {
44
+ const voucherHash = Hash.keccak256(AbiParameters.encode(voucherHashParameters, [
45
+ exports.voucherTypehash,
46
+ value.channelId,
47
+ value.cumulativeAmount,
48
+ ]));
49
+ return Hash.keccak256(Hex.concat('0x1901', domainSeparator({ chainId: value.chainId }), voucherHash));
50
+ }
51
+ //# sourceMappingURL=Channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Channel.js","sourceRoot":"","sources":["../../tempo/Channel.ts"],"names":[],"mappings":";;;AAsEA,8BAeC;AA8BD,0CAUC;AA+BD,sDAiBC;AA7KD,0DAAyD;AAEzD,wCAAuC;AACvC,sCAAqC;AACrC,4DAA2D;AAE3D,MAAM,mBAAmB,GAAG,aAAa,CAAC,IAAI,CAC5C,iFAAiF,CAClF,CAAA;AACD,MAAM,yBAAyB,GAAG,aAAa,CAAC,IAAI,CAClD,6CAA6C,CAC9C,CAAA;AACD,MAAM,qBAAqB,GAAG,aAAa,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;AAE5E,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,CACzC,GAAG,CAAC,UAAU,CACZ,oFAAoF,CACrF,CACF,CAAA;AACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC,CAAA;AACxE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;AAK1C,QAAA,OAAO,GAClB,4CAA+E,CAAA;AAKpE,QAAA,gBAAgB,GAAG,IAAI,CAAA;AAKvB,QAAA,eAAe,GAAG,IAAI,CAAC,SAAS,CAC3C,GAAG,CAAC,UAAU,CAAC,oDAAoD,CAAC,CACrE,CAAA;AAgCD,SAAgB,SAAS,CAAC,KAAsB;IAC9C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAChD,OAAO,IAAI,CAAC,SAAS,CACnB,aAAa,CAAC,MAAM,CAAC,mBAAmB,EAAE;QACxC,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,QAAQ;QACnB,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,IAAI;QACf,UAAU,CAAC,gBAAgB;QAC3B,UAAU,CAAC,iBAAiB;QAC5B,eAAO;QACP,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;KACtB,CAAC,CACH,CAAA;AACH,CAAC;AA8BD,SAAgB,eAAe,CAAC,KAA4B;IAC1D,OAAO,IAAI,CAAC,SAAS,CACnB,aAAa,CAAC,MAAM,CAAC,yBAAyB,EAAE;QAC9C,oBAAoB;QACpB,QAAQ;QACR,WAAW;QACX,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QACrB,eAAO;KACR,CAAC,CACH,CAAA;AACH,CAAC;AA+BD,SAAgB,qBAAqB,CACnC,KAAkC;IAElC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAChC,aAAa,CAAC,MAAM,CAAC,qBAAqB,EAAE;QAC1C,uBAAe;QACf,KAAK,CAAC,SAAS;QACf,KAAK,CAAC,gBAAgB;KACvB,CAAC,CACH,CAAA;IACD,OAAO,IAAI,CAAC,SAAS,CACnB,GAAG,CAAC,MAAM,CACR,QAAQ,EACR,eAAe,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAC3C,WAAW,CACZ,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.from = from;
4
+ const Address = require("../core/Address.js");
5
+ const TokenId = require("./TokenId.js");
6
+ const zeroAddress = '0x0000000000000000000000000000000000000000';
7
+ function from(value) {
8
+ const { authorizedSigner = zeroAddress, expiringNonceHash, operator = zeroAddress, payee, payer, salt, token, } = value;
9
+ return {
10
+ authorizedSigner: resolveAddress(authorizedSigner),
11
+ expiringNonceHash,
12
+ operator: resolveAddress(operator),
13
+ payee: resolveAddress(payee),
14
+ payer: resolveAddress(payer),
15
+ salt,
16
+ token: typeof token === 'string'
17
+ ? resolveAddress(token)
18
+ : TokenId.toAddress(token),
19
+ };
20
+ }
21
+ function resolveAddress(address) {
22
+ return Address.from(address);
23
+ }
24
+ //# sourceMappingURL=ChannelDescriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelDescriptor.js","sourceRoot":"","sources":["../../tempo/ChannelDescriptor.ts"],"names":[],"mappings":";;AA4DA,oBAuBC;AAnFD,8CAA6C;AAG7C,wCAAuC;AAEvC,MAAM,WAAW,GACf,4CAA+E,CAAA;AAsDjF,SAAgB,IAAI,CAAC,KAAiB;IACpC,MAAM,EACJ,gBAAgB,GAAG,WAAW,EAC9B,iBAAiB,EACjB,QAAQ,GAAG,WAAW,EACtB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,GACN,GAAG,KAAK,CAAA;IAET,OAAO;QACL,gBAAgB,EAAE,cAAc,CAAC,gBAAgB,CAAC;QAClD,iBAAiB;QACjB,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;QAClC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;QAC5B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;QAC5B,IAAI;QACJ,KAAK,EACH,OAAO,KAAK,KAAK,QAAQ;YACvB,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC;YACvB,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;KAC/B,CAAA;AACH,CAAC;AA6BD,SAAS,cAAc,CAAC,OAAwB;IAC9C,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC9B,CAAC"}
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ZoneRpcAuthentication = exports.ZoneId = exports.VirtualMaster = exports.VirtualAddress = exports.TxEnvelopeTempo = exports.TransactionRequest = exports.TransactionReceipt = exports.Transaction = exports.TokenRole = exports.TokenId = exports.Tick = exports.TempoAddress = exports.SignatureEnvelope = exports.RpcSchemaTempo = exports.PoolId = exports.Period = exports.KeyAuthorization = exports.AuthorizationTempo = void 0;
3
+ exports.ZoneRpcAuthentication = exports.ZoneId = exports.VirtualMaster = exports.VirtualAddress = exports.TxEnvelopeTempo = exports.TransactionRequest = exports.TransactionReceipt = exports.Transaction = exports.TokenRole = exports.TokenId = exports.Tick = exports.TempoAddress = exports.SignatureEnvelope = exports.RpcSchemaTempo = exports.PoolId = exports.Period = exports.KeyAuthorization = exports.ChannelDescriptor = exports.Channel = exports.AuthorizationTempo = void 0;
4
4
  exports.AuthorizationTempo = require("./AuthorizationTempo.js");
5
+ exports.Channel = require("./Channel.js");
6
+ exports.ChannelDescriptor = require("./ChannelDescriptor.js");
5
7
  exports.KeyAuthorization = require("./KeyAuthorization.js");
6
8
  exports.Period = require("./Period.js");
7
9
  exports.PoolId = require("./PoolId.js");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":";;;AAoCA,gEAA6D;AAwC7D,4DAAyD;AA6BzD,wCAAqC;AAsBrC,wCAAqC;AAoBrC,wDAAqD;AAuBrD,8DAA2D;AAmB3D,oDAAiD;AAoBjD,oCAAiC;AAqBjC,0CAAuC;AAkBvC,8CAA2C;AAkD3C,kDAA+C;AAuB/C,gEAA6D;AAqB7D,gEAA6D;AA6B7D,0DAAuD;AA4BvD,wDAAqD;AAyBrD,sDAAmD;AAqBnD,wCAAqC;AAmCrC,sEAAmE"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":";;;AAoCA,gEAA6D;AA0B7D,0CAAuC;AAsBvC,8DAA2D;AAwC3D,4DAAyD;AA6BzD,wCAAqC;AAsBrC,wCAAqC;AAoBrC,wDAAqD;AAuBrD,8DAA2D;AAmB3D,oDAAiD;AAoBjD,oCAAiC;AAqBjC,0CAAuC;AAkBvC,8CAA2C;AAkD3C,kDAA+C;AAuB/C,gEAA6D;AAqB7D,gEAA6D;AA6B7D,0DAAuD;AA4BvD,wDAAqD;AAyBrD,sDAAmD;AAqBnD,wCAAqC;AAmCrC,sEAAmE"}
package/_cjs/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
- exports.version = '0.14.22';
4
+ exports.version = '0.14.24';
5
5
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,115 @@
1
+ import * as AbiParameters from '../core/AbiParameters.js';
2
+ import * as Hash from '../core/Hash.js';
3
+ import * as Hex from '../core/Hex.js';
4
+ import * as ChannelDescriptor from './ChannelDescriptor.js';
5
+ const channelIdParameters = AbiParameters.from('address, address, address, address, bytes32, address, bytes32, address, uint256');
6
+ const domainSeparatorParameters = AbiParameters.from('bytes32, bytes32, bytes32, uint256, address');
7
+ const voucherHashParameters = AbiParameters.from('bytes32, bytes32, uint96');
8
+ const eip712DomainTypehash = Hash.keccak256(Hex.fromString('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'));
9
+ const nameHash = Hash.keccak256(Hex.fromString('TIP20 Channel Reserve'));
10
+ const versionHash = Hash.keccak256(Hex.fromString('1'));
11
+ /**
12
+ * TIP-20 channel reserve precompile address.
13
+ */
14
+ export const address = '0x4d50500000000000000000000000000000000000';
15
+ /**
16
+ * Delay between payer `requestClose` and `withdraw`, in seconds.
17
+ */
18
+ export const closeGracePeriod = 900n;
19
+ /**
20
+ * EIP-712 type hash for `Voucher(bytes32 channelId,uint96 cumulativeAmount)`.
21
+ */
22
+ export const voucherTypehash = Hash.keccak256(Hex.fromString('Voucher(bytes32 channelId,uint96 cumulativeAmount)'));
23
+ /**
24
+ * Computes the canonical TIP-20 channel id for a descriptor.
25
+ *
26
+ * Mirrors `computeChannelId` on the TIP-20 channel reserve precompile without
27
+ * performing an RPC call.
28
+ *
29
+ * @example
30
+ * ```ts twoslash
31
+ * import { Channel } from 'ox/tempo'
32
+ *
33
+ * const channelId = Channel.computeId({
34
+ * authorizedSigner: '0x0000000000000000000000000000000000000000',
35
+ * chainId: 4217,
36
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
37
+ * operator: '0x0000000000000000000000000000000000000000',
38
+ * payee: '0x2222222222222222222222222222222222222222',
39
+ * payer: '0x1111111111111111111111111111111111111111',
40
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
41
+ * token: 1n,
42
+ * })
43
+ * ```
44
+ *
45
+ * @param value - Channel descriptor and chain id.
46
+ * @returns The channel id.
47
+ */
48
+ export function computeId(value) {
49
+ const descriptor = ChannelDescriptor.from(value);
50
+ return Hash.keccak256(AbiParameters.encode(channelIdParameters, [
51
+ descriptor.payer,
52
+ descriptor.payee,
53
+ descriptor.operator,
54
+ descriptor.token,
55
+ descriptor.salt,
56
+ descriptor.authorizedSigner,
57
+ descriptor.expiringNonceHash,
58
+ address,
59
+ BigInt(value.chainId),
60
+ ]));
61
+ }
62
+ /**
63
+ * Computes the EIP-712 domain separator for the TIP-20 channel reserve.
64
+ *
65
+ * Mirrors `domainSeparator` on the TIP-20 channel reserve precompile without
66
+ * performing an RPC call.
67
+ *
68
+ * @example
69
+ * ```ts twoslash
70
+ * import { Channel } from 'ox/tempo'
71
+ *
72
+ * const separator = Channel.domainSeparator({ chainId: 4217 })
73
+ * ```
74
+ *
75
+ * @param value - Chain id.
76
+ * @returns The EIP-712 domain separator.
77
+ */
78
+ export function domainSeparator(value) {
79
+ return Hash.keccak256(AbiParameters.encode(domainSeparatorParameters, [
80
+ eip712DomainTypehash,
81
+ nameHash,
82
+ versionHash,
83
+ BigInt(value.chainId),
84
+ address,
85
+ ]));
86
+ }
87
+ /**
88
+ * Computes the EIP-712 sign payload for a TIP-20 channel voucher.
89
+ *
90
+ * Mirrors `getVoucherDigest` on the TIP-20 channel reserve precompile without
91
+ * performing an RPC call.
92
+ *
93
+ * @example
94
+ * ```ts twoslash
95
+ * import { Channel } from 'ox/tempo'
96
+ *
97
+ * const payload = Channel.getVoucherSignPayload({
98
+ * chainId: 4217,
99
+ * channelId: '0x0000000000000000000000000000000000000000000000000000000000000000',
100
+ * cumulativeAmount: 1n,
101
+ * })
102
+ * ```
103
+ *
104
+ * @param value - Voucher fields and chain id.
105
+ * @returns The voucher sign payload.
106
+ */
107
+ export function getVoucherSignPayload(value) {
108
+ const voucherHash = Hash.keccak256(AbiParameters.encode(voucherHashParameters, [
109
+ voucherTypehash,
110
+ value.channelId,
111
+ value.cumulativeAmount,
112
+ ]));
113
+ return Hash.keccak256(Hex.concat('0x1901', domainSeparator({ chainId: value.chainId }), voucherHash));
114
+ }
115
+ //# sourceMappingURL=Channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Channel.js","sourceRoot":"","sources":["../../tempo/Channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAA;AAEzD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D,MAAM,mBAAmB,GAAG,aAAa,CAAC,IAAI,CAC5C,iFAAiF,CAClF,CAAA;AACD,MAAM,yBAAyB,GAAG,aAAa,CAAC,IAAI,CAClD,6CAA6C,CAC9C,CAAA;AACD,MAAM,qBAAqB,GAAG,aAAa,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;AAE5E,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,CACzC,GAAG,CAAC,UAAU,CACZ,oFAAoF,CACrF,CACF,CAAA;AACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC,CAAA;AACxE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;AAEvD;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAClB,4CAA+E,CAAA;AAEjF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAA;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAC3C,GAAG,CAAC,UAAU,CAAC,oDAAoD,CAAC,CACrE,CAAA;AAOD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,SAAS,CAAC,KAAsB;IAC9C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAChD,OAAO,IAAI,CAAC,SAAS,CACnB,aAAa,CAAC,MAAM,CAAC,mBAAmB,EAAE;QACxC,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,QAAQ;QACnB,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,IAAI;QACf,UAAU,CAAC,gBAAgB;QAC3B,UAAU,CAAC,iBAAiB;QAC5B,OAAO;QACP,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;KACtB,CAAC,CACH,CAAA;AACH,CAAC;AAcD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,KAA4B;IAC1D,OAAO,IAAI,CAAC,SAAS,CACnB,aAAa,CAAC,MAAM,CAAC,yBAAyB,EAAE;QAC9C,oBAAoB;QACpB,QAAQ;QACR,WAAW;QACX,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QACrB,OAAO;KACR,CAAC,CACH,CAAA;AACH,CAAC;AAWD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAkC;IAElC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAChC,aAAa,CAAC,MAAM,CAAC,qBAAqB,EAAE;QAC1C,eAAe;QACf,KAAK,CAAC,SAAS;QACf,KAAK,CAAC,gBAAgB;KACvB,CAAC,CACH,CAAA;IACD,OAAO,IAAI,CAAC,SAAS,CACnB,GAAG,CAAC,MAAM,CACR,QAAQ,EACR,eAAe,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAC3C,WAAW,CACZ,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ import * as Address from '../core/Address.js';
2
+ import * as TokenId from './TokenId.js';
3
+ const zeroAddress = '0x0000000000000000000000000000000000000000';
4
+ /**
5
+ * Instantiates a TIP-20 channel reserve descriptor.
6
+ *
7
+ * Accepts a TIP-20 token ID or address, and defaults `operator` and
8
+ * `authorizedSigner` to the zero address.
9
+ *
10
+ * @example
11
+ * ```ts twoslash
12
+ * import { ChannelDescriptor } from 'ox/tempo'
13
+ *
14
+ * const descriptor = ChannelDescriptor.from({
15
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000002',
16
+ * payee: '0x2222222222222222222222222222222222222222',
17
+ * payer: '0x1111111111111111111111111111111111111111',
18
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
19
+ * token: 1n,
20
+ * })
21
+ * ```
22
+ *
23
+ * @param value - The descriptor input.
24
+ * @returns The normalized channel descriptor.
25
+ */
26
+ export function from(value) {
27
+ const { authorizedSigner = zeroAddress, expiringNonceHash, operator = zeroAddress, payee, payer, salt, token, } = value;
28
+ return {
29
+ authorizedSigner: resolveAddress(authorizedSigner),
30
+ expiringNonceHash,
31
+ operator: resolveAddress(operator),
32
+ payee: resolveAddress(payee),
33
+ payer: resolveAddress(payer),
34
+ salt,
35
+ token: typeof token === 'string'
36
+ ? resolveAddress(token)
37
+ : TokenId.toAddress(token),
38
+ };
39
+ }
40
+ function resolveAddress(address) {
41
+ return Address.from(address);
42
+ }
43
+ //# sourceMappingURL=ChannelDescriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelDescriptor.js","sourceRoot":"","sources":["../../tempo/ChannelDescriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAG7C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,MAAM,WAAW,GACf,4CAA+E,CAAA;AAgCjF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,IAAI,CAAC,KAAiB;IACpC,MAAM,EACJ,gBAAgB,GAAG,WAAW,EAC9B,iBAAiB,EACjB,QAAQ,GAAG,WAAW,EACtB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,GACN,GAAG,KAAK,CAAA;IAET,OAAO;QACL,gBAAgB,EAAE,cAAc,CAAC,gBAAgB,CAAC;QAClD,iBAAiB;QACjB,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;QAClC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;QAC5B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;QAC5B,IAAI;QACJ,KAAK,EACH,OAAO,KAAK,KAAK,QAAQ;YACvB,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC;YACvB,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;KAC/B,CAAA;AACH,CAAC;AA6BD,SAAS,cAAc,CAAC,OAAwB;IAC9C,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC9B,CAAC"}
@@ -31,6 +31,54 @@
31
31
  * @category Reference
32
32
  */
33
33
  export * as AuthorizationTempo from './AuthorizationTempo.js';
34
+ /**
35
+ * TIP-20 channel reserve constants and deterministic hashing utilities.
36
+ *
37
+ * The channel reserve precompile exposes helper methods for channel identifiers,
38
+ * voucher sign payloads, and its EIP-712 domain separator. These utilities compute the
39
+ * same values locally when the chain id and channel fields are known.
40
+ *
41
+ * @example
42
+ * ```ts twoslash
43
+ * import { Channel } from 'ox/tempo'
44
+ *
45
+ * const channelId = Channel.computeId({
46
+ * authorizedSigner: '0x0000000000000000000000000000000000000000',
47
+ * chainId: 4217,
48
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
49
+ * operator: '0x0000000000000000000000000000000000000000',
50
+ * payee: '0x2222222222222222222222222222222222222222',
51
+ * payer: '0x1111111111111111111111111111111111111111',
52
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
53
+ * token: 1n,
54
+ * })
55
+ * ```
56
+ *
57
+ * @category Reference
58
+ */
59
+ export * as Channel from './Channel.js';
60
+ /**
61
+ * TIP-20 channel reserve descriptor utilities.
62
+ *
63
+ * Channel descriptors are emitted by `Channel.open` and then reused to settle,
64
+ * top up, close, request close, withdraw, or compute the channel ID.
65
+ *
66
+ * @example
67
+ * ```ts twoslash
68
+ * import { ChannelDescriptor } from 'ox/tempo'
69
+ *
70
+ * const descriptor = ChannelDescriptor.from({
71
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
72
+ * payee: '0x2222222222222222222222222222222222222222',
73
+ * payer: '0x1111111111111111111111111111111111111111',
74
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
75
+ * token: 1n,
76
+ * })
77
+ * ```
78
+ *
79
+ * @category Reference
80
+ */
81
+ export * as ChannelDescriptor from './ChannelDescriptor.js';
34
82
  /**
35
83
  * Tempo key authorization utilities for provisioning and signing access keys.
36
84
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA"}
package/_esm/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /** @internal */
2
- export const version = '0.14.22';
2
+ export const version = '0.14.24';
3
3
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,110 @@
1
+ import * as AbiParameters from '../core/AbiParameters.js';
2
+ import * as Hash from '../core/Hash.js';
3
+ import * as Hex from '../core/Hex.js';
4
+ import * as ChannelDescriptor from './ChannelDescriptor.js';
5
+ /**
6
+ * TIP-20 channel reserve precompile address.
7
+ */
8
+ export declare const address: "0x4d50500000000000000000000000000000000000";
9
+ /**
10
+ * Delay between payer `requestClose` and `withdraw`, in seconds.
11
+ */
12
+ export declare const closeGracePeriod = 900n;
13
+ /**
14
+ * EIP-712 type hash for `Voucher(bytes32 channelId,uint96 cumulativeAmount)`.
15
+ */
16
+ export declare const voucherTypehash: `0x${string}`;
17
+ /**
18
+ * TIP-20 channel descriptor.
19
+ */
20
+ export type Descriptor = ChannelDescriptor.ChannelDescriptor;
21
+ /**
22
+ * Computes the canonical TIP-20 channel id for a descriptor.
23
+ *
24
+ * Mirrors `computeChannelId` on the TIP-20 channel reserve precompile without
25
+ * performing an RPC call.
26
+ *
27
+ * @example
28
+ * ```ts twoslash
29
+ * import { Channel } from 'ox/tempo'
30
+ *
31
+ * const channelId = Channel.computeId({
32
+ * authorizedSigner: '0x0000000000000000000000000000000000000000',
33
+ * chainId: 4217,
34
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
35
+ * operator: '0x0000000000000000000000000000000000000000',
36
+ * payee: '0x2222222222222222222222222222222222222222',
37
+ * payer: '0x1111111111111111111111111111111111111111',
38
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
39
+ * token: 1n,
40
+ * })
41
+ * ```
42
+ *
43
+ * @param value - Channel descriptor and chain id.
44
+ * @returns The channel id.
45
+ */
46
+ export declare function computeId(value: computeId.Value): Hex.Hex;
47
+ export declare namespace computeId {
48
+ type Value = ChannelDescriptor.from.Value & {
49
+ /** Chain id used by the channel reserve precompile. */
50
+ chainId: number | bigint;
51
+ };
52
+ type ErrorType = AbiParameters.encode.ErrorType | ChannelDescriptor.from.ErrorType | Hash.keccak256.ErrorType;
53
+ }
54
+ /**
55
+ * Computes the EIP-712 domain separator for the TIP-20 channel reserve.
56
+ *
57
+ * Mirrors `domainSeparator` on the TIP-20 channel reserve precompile without
58
+ * performing an RPC call.
59
+ *
60
+ * @example
61
+ * ```ts twoslash
62
+ * import { Channel } from 'ox/tempo'
63
+ *
64
+ * const separator = Channel.domainSeparator({ chainId: 4217 })
65
+ * ```
66
+ *
67
+ * @param value - Chain id.
68
+ * @returns The EIP-712 domain separator.
69
+ */
70
+ export declare function domainSeparator(value: domainSeparator.Value): Hex.Hex;
71
+ export declare namespace domainSeparator {
72
+ type Value = {
73
+ /** Chain id used by the channel reserve precompile. */
74
+ chainId: number | bigint;
75
+ };
76
+ type ErrorType = AbiParameters.encode.ErrorType | Hash.keccak256.ErrorType;
77
+ }
78
+ /**
79
+ * Computes the EIP-712 sign payload for a TIP-20 channel voucher.
80
+ *
81
+ * Mirrors `getVoucherDigest` on the TIP-20 channel reserve precompile without
82
+ * performing an RPC call.
83
+ *
84
+ * @example
85
+ * ```ts twoslash
86
+ * import { Channel } from 'ox/tempo'
87
+ *
88
+ * const payload = Channel.getVoucherSignPayload({
89
+ * chainId: 4217,
90
+ * channelId: '0x0000000000000000000000000000000000000000000000000000000000000000',
91
+ * cumulativeAmount: 1n,
92
+ * })
93
+ * ```
94
+ *
95
+ * @param value - Voucher fields and chain id.
96
+ * @returns The voucher sign payload.
97
+ */
98
+ export declare function getVoucherSignPayload(value: getVoucherSignPayload.Value): Hex.Hex;
99
+ export declare namespace getVoucherSignPayload {
100
+ type Value = {
101
+ /** Chain id used by the channel reserve precompile. */
102
+ chainId: number | bigint;
103
+ /** Channel id. */
104
+ channelId: Hex.Hex;
105
+ /** Total voucher amount signed for the channel. */
106
+ cumulativeAmount: bigint;
107
+ };
108
+ type ErrorType = AbiParameters.encode.ErrorType | domainSeparator.ErrorType | Hash.keccak256.ErrorType;
109
+ }
110
+ //# sourceMappingURL=Channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Channel.d.ts","sourceRoot":"","sources":["../../tempo/Channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAA;AAEzD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAkB3D;;GAEG;AACH,eAAO,MAAM,OAAO,8CAC6D,CAAA;AAEjF;;GAEG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAEpC;;GAEG;AACH,eAAO,MAAM,eAAe,eAE3B,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC,iBAAiB,CAAA;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAezD;AAED,MAAM,CAAC,OAAO,WAAW,SAAS,CAAC;IACjC,KAAK,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,GAAG;QAC1C,uDAAuD;QACvD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KACzB,CAAA;IAED,KAAK,SAAS,GACV,aAAa,CAAC,MAAM,CAAC,SAAS,GAC9B,iBAAiB,CAAC,IAAI,CAAC,SAAS,GAChC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAA;CAC7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAUrE;AAED,MAAM,CAAC,OAAO,WAAW,eAAe,CAAC;IACvC,KAAK,KAAK,GAAG;QACX,uDAAuD;QACvD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KACzB,CAAA;IAED,KAAK,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAA;CAC3E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,qBAAqB,CAAC,KAAK,GACjC,GAAG,CAAC,GAAG,CAeT;AAED,MAAM,CAAC,OAAO,WAAW,qBAAqB,CAAC;IAC7C,KAAK,KAAK,GAAG;QACX,uDAAuD;QACvD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;QACxB,kBAAkB;QAClB,SAAS,EAAE,GAAG,CAAC,GAAG,CAAA;QAClB,mDAAmD;QACnD,gBAAgB,EAAE,MAAM,CAAA;KACzB,CAAA;IAED,KAAK,SAAS,GACV,aAAa,CAAC,MAAM,CAAC,SAAS,GAC9B,eAAe,CAAC,SAAS,GACzB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAA;CAC7B"}
@@ -0,0 +1,73 @@
1
+ import * as Address from '../core/Address.js';
2
+ import type * as Errors from '../core/Errors.js';
3
+ import type * as Hex from '../core/Hex.js';
4
+ import * as TokenId from './TokenId.js';
5
+ /**
6
+ * TIP-20 channel reserve descriptor.
7
+ *
8
+ * Descriptors identify a channel without reading chain state. They are emitted
9
+ * by `open` and reused by `settle`, `topUp`, `close`, `requestClose`, and
10
+ * `withdraw`.
11
+ */
12
+ export type ChannelDescriptor<addressType = Address.Address, tokenType = TokenId.TokenIdOrAddress<addressType>> = {
13
+ /** Account that funded the channel and receives refunds. */
14
+ payer: addressType;
15
+ /** Account that receives settled voucher payments. */
16
+ payee: addressType;
17
+ /** Optional relayer allowed to submit `settle` for the payee. */
18
+ operator: addressType;
19
+ /** TIP-20 token address held by the channel. */
20
+ token: tokenType;
21
+ /** User-supplied salt to distinguish otherwise identical channels. */
22
+ salt: Hex.Hex;
23
+ /** Optional signer for vouchers. Zero means `payer` signs. */
24
+ authorizedSigner: addressType;
25
+ /** Transaction-derived hash assigned when the channel was opened. */
26
+ expiringNonceHash: Hex.Hex;
27
+ };
28
+ /** Hex-address-normalized {@link ox#ChannelDescriptor.ChannelDescriptor}. */
29
+ export type Resolved = ChannelDescriptor<Address.Address, Address.Address>;
30
+ /**
31
+ * Instantiates a TIP-20 channel reserve descriptor.
32
+ *
33
+ * Accepts a TIP-20 token ID or address, and defaults `operator` and
34
+ * `authorizedSigner` to the zero address.
35
+ *
36
+ * @example
37
+ * ```ts twoslash
38
+ * import { ChannelDescriptor } from 'ox/tempo'
39
+ *
40
+ * const descriptor = ChannelDescriptor.from({
41
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000002',
42
+ * payee: '0x2222222222222222222222222222222222222222',
43
+ * payer: '0x1111111111111111111111111111111111111111',
44
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
45
+ * token: 1n,
46
+ * })
47
+ * ```
48
+ *
49
+ * @param value - The descriptor input.
50
+ * @returns The normalized channel descriptor.
51
+ */
52
+ export declare function from(value: from.Value): from.ReturnType;
53
+ export declare namespace from {
54
+ type Value = {
55
+ /** Account that funded the channel and receives refunds. */
56
+ payer: Address.Address;
57
+ /** Account that receives settled voucher payments. */
58
+ payee: Address.Address;
59
+ /** Optional relayer allowed to submit `settle` for the payee. */
60
+ operator?: Address.Address | undefined;
61
+ /** TIP-20 token address or ID held by the channel. */
62
+ token: TokenId.TokenIdOrAddress<Address.Address>;
63
+ /** User-supplied salt to distinguish otherwise identical channels. */
64
+ salt: Hex.Hex;
65
+ /** Optional signer for vouchers. Zero means `payer` signs. */
66
+ authorizedSigner?: Address.Address | undefined;
67
+ /** Transaction-derived hash assigned when the channel was opened. */
68
+ expiringNonceHash: Hex.Hex;
69
+ };
70
+ type ReturnType = Resolved;
71
+ type ErrorType = Address.from.ErrorType | Hex.concat.ErrorType | Hex.fromNumber.ErrorType | Errors.GlobalErrorType;
72
+ }
73
+ //# sourceMappingURL=ChannelDescriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelDescriptor.d.ts","sourceRoot":"","sources":["../../tempo/ChannelDescriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,KAAK,GAAG,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAKvC;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,CAC3B,WAAW,GAAG,OAAO,CAAC,OAAO,EAC7B,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAC/C;IACF,4DAA4D;IAC5D,KAAK,EAAE,WAAW,CAAA;IAClB,sDAAsD;IACtD,KAAK,EAAE,WAAW,CAAA;IAClB,iEAAiE;IACjE,QAAQ,EAAE,WAAW,CAAA;IACrB,gDAAgD;IAChD,KAAK,EAAE,SAAS,CAAA;IAChB,sEAAsE;IACtE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAA;IACb,8DAA8D;IAC9D,gBAAgB,EAAE,WAAW,CAAA;IAC7B,qEAAqE;IACrE,iBAAiB,EAAE,GAAG,CAAC,GAAG,CAAA;CAC3B,CAAA;AAED,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAuBvD;AAED,MAAM,CAAC,OAAO,WAAW,IAAI,CAAC;IAC5B,KAAK,KAAK,GAAG;QACX,4DAA4D;QAC5D,KAAK,EAAE,OAAO,CAAC,OAAO,CAAA;QACtB,sDAAsD;QACtD,KAAK,EAAE,OAAO,CAAC,OAAO,CAAA;QACtB,iEAAiE;QACjE,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,SAAS,CAAA;QACtC,sDAAsD;QACtD,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAChD,sEAAsE;QACtE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAA;QACb,8DAA8D;QAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,SAAS,CAAA;QAC9C,qEAAqE;QACrE,iBAAiB,EAAE,GAAG,CAAC,GAAG,CAAA;KAC3B,CAAA;IAED,KAAK,UAAU,GAAG,QAAQ,CAAA;IAE1B,KAAK,SAAS,GACV,OAAO,CAAC,IAAI,CAAC,SAAS,GACtB,GAAG,CAAC,MAAM,CAAC,SAAS,GACpB,GAAG,CAAC,UAAU,CAAC,SAAS,GACxB,MAAM,CAAC,eAAe,CAAA;CAC3B"}
@@ -33,6 +33,54 @@ export type {};
33
33
  * @category Reference
34
34
  */
35
35
  export * as AuthorizationTempo from './AuthorizationTempo.js';
36
+ /**
37
+ * TIP-20 channel reserve constants and deterministic hashing utilities.
38
+ *
39
+ * The channel reserve precompile exposes helper methods for channel identifiers,
40
+ * voucher sign payloads, and its EIP-712 domain separator. These utilities compute the
41
+ * same values locally when the chain id and channel fields are known.
42
+ *
43
+ * @example
44
+ * ```ts twoslash
45
+ * import { Channel } from 'ox/tempo'
46
+ *
47
+ * const channelId = Channel.computeId({
48
+ * authorizedSigner: '0x0000000000000000000000000000000000000000',
49
+ * chainId: 4217,
50
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
51
+ * operator: '0x0000000000000000000000000000000000000000',
52
+ * payee: '0x2222222222222222222222222222222222222222',
53
+ * payer: '0x1111111111111111111111111111111111111111',
54
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
55
+ * token: 1n,
56
+ * })
57
+ * ```
58
+ *
59
+ * @category Reference
60
+ */
61
+ export * as Channel from './Channel.js';
62
+ /**
63
+ * TIP-20 channel reserve descriptor utilities.
64
+ *
65
+ * Channel descriptors are emitted by `Channel.open` and then reused to settle,
66
+ * top up, close, request close, withdraw, or compute the channel ID.
67
+ *
68
+ * @example
69
+ * ```ts twoslash
70
+ * import { ChannelDescriptor } from 'ox/tempo'
71
+ *
72
+ * const descriptor = ChannelDescriptor.from({
73
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
74
+ * payee: '0x2222222222222222222222222222222222222222',
75
+ * payer: '0x1111111111111111111111111111111111111111',
76
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
77
+ * token: 1n,
78
+ * })
79
+ * ```
80
+ *
81
+ * @category Reference
82
+ */
83
+ export * as ChannelDescriptor from './ChannelDescriptor.js';
36
84
  /**
37
85
  * Tempo key authorization utilities for provisioning and signing access keys.
38
86
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../tempo/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,YAAY,EAAE,CAAA;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAC3D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AACrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAA"}
@@ -1,3 +1,3 @@
1
1
  /** @internal */
2
- export declare const version = "0.14.22";
2
+ export declare const version = "0.14.24";
3
3
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ox",
3
3
  "description": "Ethereum Standard Library",
4
- "version": "0.14.22",
4
+ "version": "0.14.24",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
@@ -504,6 +504,16 @@
504
504
  "import": "./_esm/tempo/AuthorizationTempo.js",
505
505
  "default": "./_cjs/tempo/AuthorizationTempo.js"
506
506
  },
507
+ "./tempo/Channel": {
508
+ "types": "./_types/tempo/Channel.d.ts",
509
+ "import": "./_esm/tempo/Channel.js",
510
+ "default": "./_cjs/tempo/Channel.js"
511
+ },
512
+ "./tempo/ChannelDescriptor": {
513
+ "types": "./_types/tempo/ChannelDescriptor.d.ts",
514
+ "import": "./_esm/tempo/ChannelDescriptor.js",
515
+ "default": "./_cjs/tempo/ChannelDescriptor.js"
516
+ },
507
517
  "./tempo/KeyAuthorization": {
508
518
  "types": "./_types/tempo/KeyAuthorization.d.ts",
509
519
  "import": "./_esm/tempo/KeyAuthorization.js",
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "types": "../../_types/tempo/Channel.d.ts",
4
+ "main": "../../_cjs/tempo/Channel.js",
5
+ "module": "../../_esm/tempo/Channel.js"
6
+ }
@@ -0,0 +1,120 @@
1
+ import { Hash, Hex, TypedData } from 'ox'
2
+ import { Channel } from 'ox/tempo'
3
+ import { describe, expect, test } from 'vitest'
4
+
5
+ const descriptor = {
6
+ authorizedSigner: '0x3333333333333333333333333333333333333333',
7
+ chainId: 4217,
8
+ expiringNonceHash:
9
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
10
+ operator: '0x0000000000000000000000000000000000000000',
11
+ payee: '0x2222222222222222222222222222222222222222',
12
+ payer: '0x1111111111111111111111111111111111111111',
13
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
14
+ token: 1n,
15
+ } as const
16
+
17
+ describe('address', () => {
18
+ test('default', () => {
19
+ expect(Channel.address).toMatchInlineSnapshot(
20
+ `"0x4d50500000000000000000000000000000000000"`,
21
+ )
22
+ })
23
+ })
24
+
25
+ describe('closeGracePeriod', () => {
26
+ test('default', () => {
27
+ expect(Channel.closeGracePeriod).toMatchInlineSnapshot(`900n`)
28
+ })
29
+ })
30
+
31
+ describe('voucherTypehash', () => {
32
+ test('default', () => {
33
+ expect(Channel.voucherTypehash).toBe(
34
+ Hash.keccak256(
35
+ Hex.fromString('Voucher(bytes32 channelId,uint96 cumulativeAmount)'),
36
+ ),
37
+ )
38
+ expect(Channel.voucherTypehash).toMatchInlineSnapshot(
39
+ `"0x4730b4b2fe8de522475e80e010877c5b58ad10eb07fd0436615ee123f743bbe8"`,
40
+ )
41
+ })
42
+ })
43
+
44
+ describe('computeId', () => {
45
+ test('default', () => {
46
+ expect(Channel.computeId(descriptor)).toMatchInlineSnapshot(
47
+ `"0xa392474fdbb5c6753e8789236893343f11200f43ba53cca09c0cda3651946ef2"`,
48
+ )
49
+ })
50
+
51
+ test('token address input', () => {
52
+ expect(
53
+ Channel.computeId({
54
+ ...descriptor,
55
+ token: '0x20c0000000000000000000000000000000000001',
56
+ }),
57
+ ).toBe(Channel.computeId(descriptor))
58
+ })
59
+
60
+ test('chain id bigint', () => {
61
+ expect(Channel.computeId({ ...descriptor, chainId: 4217n })).toBe(
62
+ Channel.computeId(descriptor),
63
+ )
64
+ })
65
+ })
66
+
67
+ describe('domainSeparator', () => {
68
+ test('default', () => {
69
+ const separator = Channel.domainSeparator({ chainId: descriptor.chainId })
70
+
71
+ expect(separator).toBe(
72
+ TypedData.domainSeparator({
73
+ name: 'TIP20 Channel Reserve',
74
+ version: '1',
75
+ chainId: descriptor.chainId,
76
+ verifyingContract: Channel.address,
77
+ }),
78
+ )
79
+ expect(separator).toMatchInlineSnapshot(
80
+ `"0x6465ffa0b0c1e7cfc1a894ba54d79615bc06fd7cc9cfec558f3df82189d17367"`,
81
+ )
82
+ })
83
+ })
84
+
85
+ describe('getVoucherSignPayload', () => {
86
+ test('default', () => {
87
+ const channelId = Channel.computeId(descriptor)
88
+ const cumulativeAmount = 100n
89
+ const payload = Channel.getVoucherSignPayload({
90
+ chainId: descriptor.chainId,
91
+ channelId,
92
+ cumulativeAmount,
93
+ })
94
+
95
+ expect(payload).toBe(
96
+ TypedData.getSignPayload({
97
+ domain: {
98
+ name: 'TIP20 Channel Reserve',
99
+ version: '1',
100
+ chainId: descriptor.chainId,
101
+ verifyingContract: Channel.address,
102
+ },
103
+ message: {
104
+ channelId,
105
+ cumulativeAmount,
106
+ },
107
+ primaryType: 'Voucher',
108
+ types: {
109
+ Voucher: [
110
+ { name: 'channelId', type: 'bytes32' },
111
+ { name: 'cumulativeAmount', type: 'uint96' },
112
+ ],
113
+ },
114
+ }),
115
+ )
116
+ expect(payload).toMatchInlineSnapshot(
117
+ `"0x22bb33a0c0d3e04c9312dd8c70c80154e953fef495dd76ffa14388a9c7f987d3"`,
118
+ )
119
+ })
120
+ })
@@ -0,0 +1,190 @@
1
+ import * as AbiParameters from '../core/AbiParameters.js'
2
+ import type * as Address from '../core/Address.js'
3
+ import * as Hash from '../core/Hash.js'
4
+ import * as Hex from '../core/Hex.js'
5
+ import * as ChannelDescriptor from './ChannelDescriptor.js'
6
+
7
+ const channelIdParameters = AbiParameters.from(
8
+ 'address, address, address, address, bytes32, address, bytes32, address, uint256',
9
+ )
10
+ const domainSeparatorParameters = AbiParameters.from(
11
+ 'bytes32, bytes32, bytes32, uint256, address',
12
+ )
13
+ const voucherHashParameters = AbiParameters.from('bytes32, bytes32, uint96')
14
+
15
+ const eip712DomainTypehash = Hash.keccak256(
16
+ Hex.fromString(
17
+ 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)',
18
+ ),
19
+ )
20
+ const nameHash = Hash.keccak256(Hex.fromString('TIP20 Channel Reserve'))
21
+ const versionHash = Hash.keccak256(Hex.fromString('1'))
22
+
23
+ /**
24
+ * TIP-20 channel reserve precompile address.
25
+ */
26
+ export const address =
27
+ '0x4d50500000000000000000000000000000000000' as const satisfies Address.Address
28
+
29
+ /**
30
+ * Delay between payer `requestClose` and `withdraw`, in seconds.
31
+ */
32
+ export const closeGracePeriod = 900n
33
+
34
+ /**
35
+ * EIP-712 type hash for `Voucher(bytes32 channelId,uint96 cumulativeAmount)`.
36
+ */
37
+ export const voucherTypehash = Hash.keccak256(
38
+ Hex.fromString('Voucher(bytes32 channelId,uint96 cumulativeAmount)'),
39
+ )
40
+
41
+ /**
42
+ * TIP-20 channel descriptor.
43
+ */
44
+ export type Descriptor = ChannelDescriptor.ChannelDescriptor
45
+
46
+ /**
47
+ * Computes the canonical TIP-20 channel id for a descriptor.
48
+ *
49
+ * Mirrors `computeChannelId` on the TIP-20 channel reserve precompile without
50
+ * performing an RPC call.
51
+ *
52
+ * @example
53
+ * ```ts twoslash
54
+ * import { Channel } from 'ox/tempo'
55
+ *
56
+ * const channelId = Channel.computeId({
57
+ * authorizedSigner: '0x0000000000000000000000000000000000000000',
58
+ * chainId: 4217,
59
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
60
+ * operator: '0x0000000000000000000000000000000000000000',
61
+ * payee: '0x2222222222222222222222222222222222222222',
62
+ * payer: '0x1111111111111111111111111111111111111111',
63
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
64
+ * token: 1n,
65
+ * })
66
+ * ```
67
+ *
68
+ * @param value - Channel descriptor and chain id.
69
+ * @returns The channel id.
70
+ */
71
+ export function computeId(value: computeId.Value): Hex.Hex {
72
+ const descriptor = ChannelDescriptor.from(value)
73
+ return Hash.keccak256(
74
+ AbiParameters.encode(channelIdParameters, [
75
+ descriptor.payer,
76
+ descriptor.payee,
77
+ descriptor.operator,
78
+ descriptor.token,
79
+ descriptor.salt,
80
+ descriptor.authorizedSigner,
81
+ descriptor.expiringNonceHash,
82
+ address,
83
+ BigInt(value.chainId),
84
+ ]),
85
+ )
86
+ }
87
+
88
+ export declare namespace computeId {
89
+ type Value = ChannelDescriptor.from.Value & {
90
+ /** Chain id used by the channel reserve precompile. */
91
+ chainId: number | bigint
92
+ }
93
+
94
+ type ErrorType =
95
+ | AbiParameters.encode.ErrorType
96
+ | ChannelDescriptor.from.ErrorType
97
+ | Hash.keccak256.ErrorType
98
+ }
99
+
100
+ /**
101
+ * Computes the EIP-712 domain separator for the TIP-20 channel reserve.
102
+ *
103
+ * Mirrors `domainSeparator` on the TIP-20 channel reserve precompile without
104
+ * performing an RPC call.
105
+ *
106
+ * @example
107
+ * ```ts twoslash
108
+ * import { Channel } from 'ox/tempo'
109
+ *
110
+ * const separator = Channel.domainSeparator({ chainId: 4217 })
111
+ * ```
112
+ *
113
+ * @param value - Chain id.
114
+ * @returns The EIP-712 domain separator.
115
+ */
116
+ export function domainSeparator(value: domainSeparator.Value): Hex.Hex {
117
+ return Hash.keccak256(
118
+ AbiParameters.encode(domainSeparatorParameters, [
119
+ eip712DomainTypehash,
120
+ nameHash,
121
+ versionHash,
122
+ BigInt(value.chainId),
123
+ address,
124
+ ]),
125
+ )
126
+ }
127
+
128
+ export declare namespace domainSeparator {
129
+ type Value = {
130
+ /** Chain id used by the channel reserve precompile. */
131
+ chainId: number | bigint
132
+ }
133
+
134
+ type ErrorType = AbiParameters.encode.ErrorType | Hash.keccak256.ErrorType
135
+ }
136
+
137
+ /**
138
+ * Computes the EIP-712 sign payload for a TIP-20 channel voucher.
139
+ *
140
+ * Mirrors `getVoucherDigest` on the TIP-20 channel reserve precompile without
141
+ * performing an RPC call.
142
+ *
143
+ * @example
144
+ * ```ts twoslash
145
+ * import { Channel } from 'ox/tempo'
146
+ *
147
+ * const payload = Channel.getVoucherSignPayload({
148
+ * chainId: 4217,
149
+ * channelId: '0x0000000000000000000000000000000000000000000000000000000000000000',
150
+ * cumulativeAmount: 1n,
151
+ * })
152
+ * ```
153
+ *
154
+ * @param value - Voucher fields and chain id.
155
+ * @returns The voucher sign payload.
156
+ */
157
+ export function getVoucherSignPayload(
158
+ value: getVoucherSignPayload.Value,
159
+ ): Hex.Hex {
160
+ const voucherHash = Hash.keccak256(
161
+ AbiParameters.encode(voucherHashParameters, [
162
+ voucherTypehash,
163
+ value.channelId,
164
+ value.cumulativeAmount,
165
+ ]),
166
+ )
167
+ return Hash.keccak256(
168
+ Hex.concat(
169
+ '0x1901',
170
+ domainSeparator({ chainId: value.chainId }),
171
+ voucherHash,
172
+ ),
173
+ )
174
+ }
175
+
176
+ export declare namespace getVoucherSignPayload {
177
+ type Value = {
178
+ /** Chain id used by the channel reserve precompile. */
179
+ chainId: number | bigint
180
+ /** Channel id. */
181
+ channelId: Hex.Hex
182
+ /** Total voucher amount signed for the channel. */
183
+ cumulativeAmount: bigint
184
+ }
185
+
186
+ type ErrorType =
187
+ | AbiParameters.encode.ErrorType
188
+ | domainSeparator.ErrorType
189
+ | Hash.keccak256.ErrorType
190
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "types": "../../_types/tempo/ChannelDescriptor.d.ts",
4
+ "main": "../../_cjs/tempo/ChannelDescriptor.js",
5
+ "module": "../../_esm/tempo/ChannelDescriptor.js"
6
+ }
@@ -0,0 +1,93 @@
1
+ import type { Address } from 'ox'
2
+ import { ChannelDescriptor } from 'ox/tempo'
3
+ import { describe, expect, test } from 'vitest'
4
+
5
+ describe('from', () => {
6
+ test('default', () => {
7
+ expect(
8
+ ChannelDescriptor.from({
9
+ authorizedSigner: '0x3333333333333333333333333333333333333333',
10
+ expiringNonceHash:
11
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
12
+ operator: '0x4444444444444444444444444444444444444444',
13
+ payee: '0x2222222222222222222222222222222222222222',
14
+ payer: '0x1111111111111111111111111111111111111111',
15
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
16
+ token: 1n,
17
+ }),
18
+ ).toMatchInlineSnapshot(`
19
+ {
20
+ "authorizedSigner": "0x3333333333333333333333333333333333333333",
21
+ "expiringNonceHash": "0x0000000000000000000000000000000000000000000000000000000000000002",
22
+ "operator": "0x4444444444444444444444444444444444444444",
23
+ "payee": "0x2222222222222222222222222222222222222222",
24
+ "payer": "0x1111111111111111111111111111111111111111",
25
+ "salt": "0x0000000000000000000000000000000000000000000000000000000000000001",
26
+ "token": "0x20c0000000000000000000000000000000000001",
27
+ }
28
+ `)
29
+ })
30
+
31
+ test('default values', () => {
32
+ expect(
33
+ ChannelDescriptor.from({
34
+ expiringNonceHash:
35
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
36
+ payee: '0x2222222222222222222222222222222222222222',
37
+ payer: '0x1111111111111111111111111111111111111111',
38
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
39
+ token: 1n,
40
+ }),
41
+ ).toMatchInlineSnapshot(`
42
+ {
43
+ "authorizedSigner": "0x0000000000000000000000000000000000000000",
44
+ "expiringNonceHash": "0x0000000000000000000000000000000000000000000000000000000000000002",
45
+ "operator": "0x0000000000000000000000000000000000000000",
46
+ "payee": "0x2222222222222222222222222222222222222222",
47
+ "payer": "0x1111111111111111111111111111111111111111",
48
+ "salt": "0x0000000000000000000000000000000000000000000000000000000000000001",
49
+ "token": "0x20c0000000000000000000000000000000000001",
50
+ }
51
+ `)
52
+ })
53
+
54
+ test('token address input', () => {
55
+ expect(
56
+ ChannelDescriptor.from({
57
+ authorizedSigner: '0x3333333333333333333333333333333333333333',
58
+ expiringNonceHash:
59
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
60
+ operator: '0x4444444444444444444444444444444444444444',
61
+ payee: '0x2222222222222222222222222222222222222222',
62
+ payer: '0x1111111111111111111111111111111111111111',
63
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
64
+ token: '0x20c0000000000000000000000000000000000001',
65
+ }),
66
+ ).toMatchInlineSnapshot(`
67
+ {
68
+ "authorizedSigner": "0x3333333333333333333333333333333333333333",
69
+ "expiringNonceHash": "0x0000000000000000000000000000000000000000000000000000000000000002",
70
+ "operator": "0x4444444444444444444444444444444444444444",
71
+ "payee": "0x2222222222222222222222222222222222222222",
72
+ "payer": "0x1111111111111111111111111111111111111111",
73
+ "salt": "0x0000000000000000000000000000000000000000000000000000000000000001",
74
+ "token": "0x20c0000000000000000000000000000000000001",
75
+ }
76
+ `)
77
+ })
78
+
79
+ test('return type', () => {
80
+ const descriptor = ChannelDescriptor.from({
81
+ expiringNonceHash:
82
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
83
+ payee: '0x2222222222222222222222222222222222222222',
84
+ payer: '0x1111111111111111111111111111111111111111',
85
+ salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
86
+ token: 1n,
87
+ })
88
+
89
+ descriptor satisfies ChannelDescriptor.Resolved
90
+ descriptor.payer satisfies Address.Address
91
+ descriptor.token satisfies Address.Address
92
+ })
93
+ })
@@ -0,0 +1,115 @@
1
+ import * as Address from '../core/Address.js'
2
+ import type * as Errors from '../core/Errors.js'
3
+ import type * as Hex from '../core/Hex.js'
4
+ import * as TokenId from './TokenId.js'
5
+
6
+ const zeroAddress =
7
+ '0x0000000000000000000000000000000000000000' as const satisfies Address.Address
8
+
9
+ /**
10
+ * TIP-20 channel reserve descriptor.
11
+ *
12
+ * Descriptors identify a channel without reading chain state. They are emitted
13
+ * by `open` and reused by `settle`, `topUp`, `close`, `requestClose`, and
14
+ * `withdraw`.
15
+ */
16
+ export type ChannelDescriptor<
17
+ addressType = Address.Address,
18
+ tokenType = TokenId.TokenIdOrAddress<addressType>,
19
+ > = {
20
+ /** Account that funded the channel and receives refunds. */
21
+ payer: addressType
22
+ /** Account that receives settled voucher payments. */
23
+ payee: addressType
24
+ /** Optional relayer allowed to submit `settle` for the payee. */
25
+ operator: addressType
26
+ /** TIP-20 token address held by the channel. */
27
+ token: tokenType
28
+ /** User-supplied salt to distinguish otherwise identical channels. */
29
+ salt: Hex.Hex
30
+ /** Optional signer for vouchers. Zero means `payer` signs. */
31
+ authorizedSigner: addressType
32
+ /** Transaction-derived hash assigned when the channel was opened. */
33
+ expiringNonceHash: Hex.Hex
34
+ }
35
+
36
+ /** Hex-address-normalized {@link ox#ChannelDescriptor.ChannelDescriptor}. */
37
+ export type Resolved = ChannelDescriptor<Address.Address, Address.Address>
38
+
39
+ /**
40
+ * Instantiates a TIP-20 channel reserve descriptor.
41
+ *
42
+ * Accepts a TIP-20 token ID or address, and defaults `operator` and
43
+ * `authorizedSigner` to the zero address.
44
+ *
45
+ * @example
46
+ * ```ts twoslash
47
+ * import { ChannelDescriptor } from 'ox/tempo'
48
+ *
49
+ * const descriptor = ChannelDescriptor.from({
50
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000002',
51
+ * payee: '0x2222222222222222222222222222222222222222',
52
+ * payer: '0x1111111111111111111111111111111111111111',
53
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
54
+ * token: 1n,
55
+ * })
56
+ * ```
57
+ *
58
+ * @param value - The descriptor input.
59
+ * @returns The normalized channel descriptor.
60
+ */
61
+ export function from(value: from.Value): from.ReturnType {
62
+ const {
63
+ authorizedSigner = zeroAddress,
64
+ expiringNonceHash,
65
+ operator = zeroAddress,
66
+ payee,
67
+ payer,
68
+ salt,
69
+ token,
70
+ } = value
71
+
72
+ return {
73
+ authorizedSigner: resolveAddress(authorizedSigner),
74
+ expiringNonceHash,
75
+ operator: resolveAddress(operator),
76
+ payee: resolveAddress(payee),
77
+ payer: resolveAddress(payer),
78
+ salt,
79
+ token:
80
+ typeof token === 'string'
81
+ ? resolveAddress(token)
82
+ : TokenId.toAddress(token),
83
+ }
84
+ }
85
+
86
+ export declare namespace from {
87
+ type Value = {
88
+ /** Account that funded the channel and receives refunds. */
89
+ payer: Address.Address
90
+ /** Account that receives settled voucher payments. */
91
+ payee: Address.Address
92
+ /** Optional relayer allowed to submit `settle` for the payee. */
93
+ operator?: Address.Address | undefined
94
+ /** TIP-20 token address or ID held by the channel. */
95
+ token: TokenId.TokenIdOrAddress<Address.Address>
96
+ /** User-supplied salt to distinguish otherwise identical channels. */
97
+ salt: Hex.Hex
98
+ /** Optional signer for vouchers. Zero means `payer` signs. */
99
+ authorizedSigner?: Address.Address | undefined
100
+ /** Transaction-derived hash assigned when the channel was opened. */
101
+ expiringNonceHash: Hex.Hex
102
+ }
103
+
104
+ type ReturnType = Resolved
105
+
106
+ type ErrorType =
107
+ | Address.from.ErrorType
108
+ | Hex.concat.ErrorType
109
+ | Hex.fromNumber.ErrorType
110
+ | Errors.GlobalErrorType
111
+ }
112
+
113
+ function resolveAddress(address: Address.Address): Address.Address {
114
+ return Address.from(address)
115
+ }
@@ -171,7 +171,7 @@ describe('serialize', () => {
171
171
  })
172
172
 
173
173
  const credentials = import.meta.env.VITE_TEMPO_CREDENTIALS
174
- const rpcUrl = 'https://rpc-zone-006-private.tempoxyz.dev'
174
+ const rpcUrl = 'https://rpc-zone-b.testnet.tempo.xyz'
175
175
 
176
176
  describe('e2e', () => {
177
177
  test.skipIf(!credentials)('succeeds with auth token', async () => {
package/tempo/index.ts CHANGED
@@ -35,6 +35,54 @@ export type {}
35
35
  * @category Reference
36
36
  */
37
37
  export * as AuthorizationTempo from './AuthorizationTempo.js'
38
+ /**
39
+ * TIP-20 channel reserve constants and deterministic hashing utilities.
40
+ *
41
+ * The channel reserve precompile exposes helper methods for channel identifiers,
42
+ * voucher sign payloads, and its EIP-712 domain separator. These utilities compute the
43
+ * same values locally when the chain id and channel fields are known.
44
+ *
45
+ * @example
46
+ * ```ts twoslash
47
+ * import { Channel } from 'ox/tempo'
48
+ *
49
+ * const channelId = Channel.computeId({
50
+ * authorizedSigner: '0x0000000000000000000000000000000000000000',
51
+ * chainId: 4217,
52
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
53
+ * operator: '0x0000000000000000000000000000000000000000',
54
+ * payee: '0x2222222222222222222222222222222222222222',
55
+ * payer: '0x1111111111111111111111111111111111111111',
56
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
57
+ * token: 1n,
58
+ * })
59
+ * ```
60
+ *
61
+ * @category Reference
62
+ */
63
+ export * as Channel from './Channel.js'
64
+ /**
65
+ * TIP-20 channel reserve descriptor utilities.
66
+ *
67
+ * Channel descriptors are emitted by `Channel.open` and then reused to settle,
68
+ * top up, close, request close, withdraw, or compute the channel ID.
69
+ *
70
+ * @example
71
+ * ```ts twoslash
72
+ * import { ChannelDescriptor } from 'ox/tempo'
73
+ *
74
+ * const descriptor = ChannelDescriptor.from({
75
+ * expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
76
+ * payee: '0x2222222222222222222222222222222222222222',
77
+ * payer: '0x1111111111111111111111111111111111111111',
78
+ * salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
79
+ * token: 1n,
80
+ * })
81
+ * ```
82
+ *
83
+ * @category Reference
84
+ */
85
+ export * as ChannelDescriptor from './ChannelDescriptor.js'
38
86
  /**
39
87
  * Tempo key authorization utilities for provisioning and signing access keys.
40
88
  *
package/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '0.14.22'
2
+ export const version = '0.14.24'