ox 0.14.24 → 0.14.26
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 +14 -0
- package/_cjs/tempo/Channel.js +31 -11
- package/_cjs/tempo/Channel.js.map +1 -1
- package/_cjs/tempo/KeyAuthorization.js +130 -57
- package/_cjs/tempo/KeyAuthorization.js.map +1 -1
- package/_cjs/tempo/index.js +1 -2
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/Channel.js +56 -13
- package/_esm/tempo/Channel.js.map +1 -1
- package/_esm/tempo/KeyAuthorization.js +155 -62
- package/_esm/tempo/KeyAuthorization.js.map +1 -1
- package/_esm/tempo/index.js +9 -30
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/tempo/Channel.d.ts +73 -8
- package/_types/tempo/Channel.d.ts.map +1 -1
- package/_types/tempo/KeyAuthorization.d.ts +54 -2
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +9 -30
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/package.json +2 -8
- package/tempo/Channel.test.ts +99 -16
- package/tempo/Channel.ts +127 -18
- package/tempo/KeyAuthorization.test.ts +333 -0
- package/tempo/KeyAuthorization.ts +240 -72
- package/tempo/e2e.test.ts +330 -0
- package/tempo/index.ts +9 -30
- package/version.ts +1 -1
- package/_cjs/tempo/ChannelDescriptor.js +0 -24
- package/_cjs/tempo/ChannelDescriptor.js.map +0 -1
- package/_esm/tempo/ChannelDescriptor.js +0 -43
- package/_esm/tempo/ChannelDescriptor.js.map +0 -1
- package/_types/tempo/ChannelDescriptor.d.ts +0 -73
- package/_types/tempo/ChannelDescriptor.d.ts.map +0 -1
- package/tempo/ChannelDescriptor/package.json +0 -6
- package/tempo/ChannelDescriptor.test.ts +0 -93
- package/tempo/ChannelDescriptor.ts +0 -115
package/tempo/e2e.test.ts
CHANGED
|
@@ -2662,4 +2662,334 @@ describe('behavior: keyAuthorization', () => {
|
|
|
2662
2662
|
).rejects.toThrow()
|
|
2663
2663
|
},
|
|
2664
2664
|
)
|
|
2665
|
+
|
|
2666
|
+
// TODO: remove skipIf when devnet/testnet have T5 (TIP-1053).
|
|
2667
|
+
test.skipIf(nodeEnv !== 'localnet')(
|
|
2668
|
+
'behavior: TIP-1053 witness round-trips through registration',
|
|
2669
|
+
async () => {
|
|
2670
|
+
const accessPrivateKey = Secp256k1.randomPrivateKey()
|
|
2671
|
+
const accessAddress = Address.fromPublicKey(
|
|
2672
|
+
Secp256k1.getPublicKey({ privateKey: accessPrivateKey }),
|
|
2673
|
+
)
|
|
2674
|
+
|
|
2675
|
+
// Application-defined challenge digest, bound to the authorization.
|
|
2676
|
+
const witness = Hex.random(32)
|
|
2677
|
+
|
|
2678
|
+
const keyAuth = KeyAuthorization.from({
|
|
2679
|
+
address: accessAddress,
|
|
2680
|
+
chainId: BigInt(chainId),
|
|
2681
|
+
type: 'secp256k1',
|
|
2682
|
+
witness,
|
|
2683
|
+
})
|
|
2684
|
+
|
|
2685
|
+
const keyAuth_signed = KeyAuthorization.from(keyAuth, {
|
|
2686
|
+
signature: SignatureEnvelope.from(
|
|
2687
|
+
Secp256k1.sign({
|
|
2688
|
+
payload: KeyAuthorization.getSignPayload(keyAuth),
|
|
2689
|
+
privateKey: root.privateKey,
|
|
2690
|
+
}),
|
|
2691
|
+
),
|
|
2692
|
+
})
|
|
2693
|
+
|
|
2694
|
+
const nonce = await getTransactionCount(client, {
|
|
2695
|
+
address: root.address,
|
|
2696
|
+
blockTag: 'pending',
|
|
2697
|
+
})
|
|
2698
|
+
|
|
2699
|
+
const transaction = TxEnvelopeTempo.from({
|
|
2700
|
+
calls: [{ to: '0x0000000000000000000000000000000000000000' }],
|
|
2701
|
+
chainId,
|
|
2702
|
+
feeToken: '0x20c0000000000000000000000000000000000001',
|
|
2703
|
+
keyAuthorization: keyAuth_signed,
|
|
2704
|
+
nonce: BigInt(nonce),
|
|
2705
|
+
gas: 1_000_000n,
|
|
2706
|
+
maxFeePerGas: Value.fromGwei('20'),
|
|
2707
|
+
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
2708
|
+
})
|
|
2709
|
+
|
|
2710
|
+
const signature = Secp256k1.sign({
|
|
2711
|
+
payload: TxEnvelopeTempo.getSignPayload(transaction, {
|
|
2712
|
+
from: root.address,
|
|
2713
|
+
}),
|
|
2714
|
+
privateKey: accessPrivateKey,
|
|
2715
|
+
})
|
|
2716
|
+
|
|
2717
|
+
const serialized_signed = TxEnvelopeTempo.serialize(transaction, {
|
|
2718
|
+
signature: SignatureEnvelope.from({
|
|
2719
|
+
userAddress: root.address,
|
|
2720
|
+
inner: SignatureEnvelope.from(signature),
|
|
2721
|
+
type: 'keychain',
|
|
2722
|
+
}),
|
|
2723
|
+
})
|
|
2724
|
+
|
|
2725
|
+
const receipt = (await client
|
|
2726
|
+
.request({
|
|
2727
|
+
method: 'eth_sendRawTransactionSync',
|
|
2728
|
+
params: [serialized_signed],
|
|
2729
|
+
})
|
|
2730
|
+
.then((tx) => TransactionReceipt.fromRpc(tx as any)))!
|
|
2731
|
+
expect(receipt.status).toBe('success')
|
|
2732
|
+
|
|
2733
|
+
const response = await client
|
|
2734
|
+
.request({
|
|
2735
|
+
method: 'eth_getTransactionByHash',
|
|
2736
|
+
params: [receipt.transactionHash],
|
|
2737
|
+
})
|
|
2738
|
+
.then((tx) => Transaction.fromRpc(tx as any))
|
|
2739
|
+
if (!response) throw new Error()
|
|
2740
|
+
|
|
2741
|
+
// The witness must survive the round trip through the node.
|
|
2742
|
+
expect(response.keyAuthorization?.witness).toBe(witness)
|
|
2743
|
+
|
|
2744
|
+
// The signing hash of the round-tripped authorization equals the witness-bearing hash.
|
|
2745
|
+
expect(KeyAuthorization.hash(response.keyAuthorization!)).toBe(
|
|
2746
|
+
KeyAuthorization.hash(keyAuth_signed),
|
|
2747
|
+
)
|
|
2748
|
+
},
|
|
2749
|
+
)
|
|
2750
|
+
|
|
2751
|
+
// TODO: remove skipIf when devnet/testnet have T5
|
|
2752
|
+
test.skipIf(nodeEnv !== 'localnet')(
|
|
2753
|
+
'behavior: TIP-1053 witness-less authorization is byte-equivalent to pre-TIP-1053',
|
|
2754
|
+
async () => {
|
|
2755
|
+
// Two authorizations with identical fields but different access keys; the witness-less
|
|
2756
|
+
// shape must encode without a trailing witness slot.
|
|
2757
|
+
const accessPrivateKey = Secp256k1.randomPrivateKey()
|
|
2758
|
+
const accessAddress = Address.fromPublicKey(
|
|
2759
|
+
Secp256k1.getPublicKey({ privateKey: accessPrivateKey }),
|
|
2760
|
+
)
|
|
2761
|
+
const keyAuth = KeyAuthorization.from({
|
|
2762
|
+
address: accessAddress,
|
|
2763
|
+
chainId: BigInt(chainId),
|
|
2764
|
+
type: 'secp256k1',
|
|
2765
|
+
})
|
|
2766
|
+
const [authTuple] = KeyAuthorization.toTuple(keyAuth)
|
|
2767
|
+
expect((authTuple as unknown as unknown[]).length).toBe(3)
|
|
2768
|
+
|
|
2769
|
+
const keyAuth_signed = KeyAuthorization.from(keyAuth, {
|
|
2770
|
+
signature: SignatureEnvelope.from(
|
|
2771
|
+
Secp256k1.sign({
|
|
2772
|
+
payload: KeyAuthorization.getSignPayload(keyAuth),
|
|
2773
|
+
privateKey: root.privateKey,
|
|
2774
|
+
}),
|
|
2775
|
+
),
|
|
2776
|
+
})
|
|
2777
|
+
|
|
2778
|
+
const nonce = await getTransactionCount(client, {
|
|
2779
|
+
address: root.address,
|
|
2780
|
+
blockTag: 'pending',
|
|
2781
|
+
})
|
|
2782
|
+
|
|
2783
|
+
const transaction = TxEnvelopeTempo.from({
|
|
2784
|
+
calls: [{ to: '0x0000000000000000000000000000000000000000' }],
|
|
2785
|
+
chainId,
|
|
2786
|
+
feeToken: '0x20c0000000000000000000000000000000000001',
|
|
2787
|
+
keyAuthorization: keyAuth_signed,
|
|
2788
|
+
nonce: BigInt(nonce),
|
|
2789
|
+
gas: 1_000_000n,
|
|
2790
|
+
maxFeePerGas: Value.fromGwei('20'),
|
|
2791
|
+
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
2792
|
+
})
|
|
2793
|
+
|
|
2794
|
+
const signature = Secp256k1.sign({
|
|
2795
|
+
payload: TxEnvelopeTempo.getSignPayload(transaction, {
|
|
2796
|
+
from: root.address,
|
|
2797
|
+
}),
|
|
2798
|
+
privateKey: accessPrivateKey,
|
|
2799
|
+
})
|
|
2800
|
+
|
|
2801
|
+
const serialized_signed = TxEnvelopeTempo.serialize(transaction, {
|
|
2802
|
+
signature: SignatureEnvelope.from({
|
|
2803
|
+
userAddress: root.address,
|
|
2804
|
+
inner: SignatureEnvelope.from(signature),
|
|
2805
|
+
type: 'keychain',
|
|
2806
|
+
}),
|
|
2807
|
+
})
|
|
2808
|
+
|
|
2809
|
+
const receipt = (await client
|
|
2810
|
+
.request({
|
|
2811
|
+
method: 'eth_sendRawTransactionSync',
|
|
2812
|
+
params: [serialized_signed],
|
|
2813
|
+
})
|
|
2814
|
+
.then((tx) => TransactionReceipt.fromRpc(tx as any)))!
|
|
2815
|
+
expect(receipt.status).toBe('success')
|
|
2816
|
+
|
|
2817
|
+
const response = await client
|
|
2818
|
+
.request({
|
|
2819
|
+
method: 'eth_getTransactionByHash',
|
|
2820
|
+
params: [receipt.transactionHash],
|
|
2821
|
+
})
|
|
2822
|
+
.then((tx) => Transaction.fromRpc(tx as any))
|
|
2823
|
+
if (!response) throw new Error()
|
|
2824
|
+
|
|
2825
|
+
expect(response.keyAuthorization?.witness).toBeUndefined()
|
|
2826
|
+
},
|
|
2827
|
+
)
|
|
2828
|
+
|
|
2829
|
+
// TODO: remove skipIf when devnet/testnet have T6 (TIP-1049).
|
|
2830
|
+
test.skipIf(nodeEnv !== 'localnet')(
|
|
2831
|
+
'behavior: TIP-1049 admin access key round-trips through registration',
|
|
2832
|
+
async () => {
|
|
2833
|
+
const accessPrivateKey = Secp256k1.randomPrivateKey()
|
|
2834
|
+
const accessAddress = Address.fromPublicKey(
|
|
2835
|
+
Secp256k1.getPublicKey({ privateKey: accessPrivateKey }),
|
|
2836
|
+
)
|
|
2837
|
+
|
|
2838
|
+
const keyAuth = KeyAuthorization.from({
|
|
2839
|
+
address: accessAddress,
|
|
2840
|
+
account: root.address,
|
|
2841
|
+
chainId: BigInt(chainId),
|
|
2842
|
+
isAdmin: true,
|
|
2843
|
+
type: 'secp256k1',
|
|
2844
|
+
})
|
|
2845
|
+
|
|
2846
|
+
const keyAuth_signed = KeyAuthorization.from(keyAuth, {
|
|
2847
|
+
signature: SignatureEnvelope.from(
|
|
2848
|
+
Secp256k1.sign({
|
|
2849
|
+
payload: KeyAuthorization.getSignPayload(keyAuth),
|
|
2850
|
+
privateKey: root.privateKey,
|
|
2851
|
+
}),
|
|
2852
|
+
),
|
|
2853
|
+
})
|
|
2854
|
+
|
|
2855
|
+
const nonce = await getTransactionCount(client, {
|
|
2856
|
+
address: root.address,
|
|
2857
|
+
blockTag: 'pending',
|
|
2858
|
+
})
|
|
2859
|
+
|
|
2860
|
+
const transaction = TxEnvelopeTempo.from({
|
|
2861
|
+
calls: [{ to: '0x0000000000000000000000000000000000000000' }],
|
|
2862
|
+
chainId,
|
|
2863
|
+
feeToken: '0x20c0000000000000000000000000000000000001',
|
|
2864
|
+
keyAuthorization: keyAuth_signed,
|
|
2865
|
+
nonce: BigInt(nonce),
|
|
2866
|
+
gas: 1_000_000n,
|
|
2867
|
+
maxFeePerGas: Value.fromGwei('20'),
|
|
2868
|
+
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
2869
|
+
})
|
|
2870
|
+
|
|
2871
|
+
// The admin access key signs and authorizes itself in the same tx
|
|
2872
|
+
// (the canonical "auth+use" registration pattern).
|
|
2873
|
+
const signature = Secp256k1.sign({
|
|
2874
|
+
payload: TxEnvelopeTempo.getSignPayload(transaction, {
|
|
2875
|
+
from: root.address,
|
|
2876
|
+
}),
|
|
2877
|
+
privateKey: accessPrivateKey,
|
|
2878
|
+
})
|
|
2879
|
+
|
|
2880
|
+
const serialized_signed = TxEnvelopeTempo.serialize(transaction, {
|
|
2881
|
+
signature: SignatureEnvelope.from({
|
|
2882
|
+
userAddress: root.address,
|
|
2883
|
+
inner: SignatureEnvelope.from(signature),
|
|
2884
|
+
type: 'keychain',
|
|
2885
|
+
}),
|
|
2886
|
+
})
|
|
2887
|
+
|
|
2888
|
+
const receipt = (await client
|
|
2889
|
+
.request({
|
|
2890
|
+
method: 'eth_sendRawTransactionSync',
|
|
2891
|
+
params: [serialized_signed],
|
|
2892
|
+
})
|
|
2893
|
+
.then((tx) => TransactionReceipt.fromRpc(tx as any)))!
|
|
2894
|
+
expect(receipt.status).toBe('success')
|
|
2895
|
+
|
|
2896
|
+
const response = await client
|
|
2897
|
+
.request({
|
|
2898
|
+
method: 'eth_getTransactionByHash',
|
|
2899
|
+
params: [receipt.transactionHash],
|
|
2900
|
+
})
|
|
2901
|
+
.then((tx) => Transaction.fromRpc(tx as any))
|
|
2902
|
+
if (!response) throw new Error()
|
|
2903
|
+
|
|
2904
|
+
// isAdmin + account must survive the round trip through the node.
|
|
2905
|
+
expect(response.keyAuthorization?.isAdmin).toBe(true)
|
|
2906
|
+
expect(response.keyAuthorization?.account).toBe(root.address)
|
|
2907
|
+
|
|
2908
|
+
// The signing hash of the round-tripped authorization equals the
|
|
2909
|
+
// admin-bearing hash.
|
|
2910
|
+
expect(KeyAuthorization.hash(response.keyAuthorization!)).toBe(
|
|
2911
|
+
KeyAuthorization.hash(keyAuth_signed),
|
|
2912
|
+
)
|
|
2913
|
+
},
|
|
2914
|
+
)
|
|
2915
|
+
|
|
2916
|
+
// TODO: remove skipIf when devnet/testnet have T6.
|
|
2917
|
+
test.skipIf(nodeEnv !== 'localnet')(
|
|
2918
|
+
'behavior: TIP-1049 non-admin authorization is byte-equivalent to pre-TIP-1049',
|
|
2919
|
+
async () => {
|
|
2920
|
+
const accessPrivateKey = Secp256k1.randomPrivateKey()
|
|
2921
|
+
const accessAddress = Address.fromPublicKey(
|
|
2922
|
+
Secp256k1.getPublicKey({ privateKey: accessPrivateKey }),
|
|
2923
|
+
)
|
|
2924
|
+
|
|
2925
|
+
// Without isAdmin or account, the encoded tuple must not carry trailing
|
|
2926
|
+
// TIP-1049 slots.
|
|
2927
|
+
const keyAuth = KeyAuthorization.from({
|
|
2928
|
+
address: accessAddress,
|
|
2929
|
+
chainId: BigInt(chainId),
|
|
2930
|
+
type: 'secp256k1',
|
|
2931
|
+
})
|
|
2932
|
+
const [authTuple] = KeyAuthorization.toTuple(keyAuth)
|
|
2933
|
+
expect((authTuple as unknown as unknown[]).length).toBe(3)
|
|
2934
|
+
|
|
2935
|
+
const keyAuth_signed = KeyAuthorization.from(keyAuth, {
|
|
2936
|
+
signature: SignatureEnvelope.from(
|
|
2937
|
+
Secp256k1.sign({
|
|
2938
|
+
payload: KeyAuthorization.getSignPayload(keyAuth),
|
|
2939
|
+
privateKey: root.privateKey,
|
|
2940
|
+
}),
|
|
2941
|
+
),
|
|
2942
|
+
})
|
|
2943
|
+
|
|
2944
|
+
const nonce = await getTransactionCount(client, {
|
|
2945
|
+
address: root.address,
|
|
2946
|
+
blockTag: 'pending',
|
|
2947
|
+
})
|
|
2948
|
+
|
|
2949
|
+
const transaction = TxEnvelopeTempo.from({
|
|
2950
|
+
calls: [{ to: '0x0000000000000000000000000000000000000000' }],
|
|
2951
|
+
chainId,
|
|
2952
|
+
feeToken: '0x20c0000000000000000000000000000000000001',
|
|
2953
|
+
keyAuthorization: keyAuth_signed,
|
|
2954
|
+
nonce: BigInt(nonce),
|
|
2955
|
+
gas: 1_000_000n,
|
|
2956
|
+
maxFeePerGas: Value.fromGwei('20'),
|
|
2957
|
+
maxPriorityFeePerGas: Value.fromGwei('10'),
|
|
2958
|
+
})
|
|
2959
|
+
|
|
2960
|
+
const signature = Secp256k1.sign({
|
|
2961
|
+
payload: TxEnvelopeTempo.getSignPayload(transaction, {
|
|
2962
|
+
from: root.address,
|
|
2963
|
+
}),
|
|
2964
|
+
privateKey: accessPrivateKey,
|
|
2965
|
+
})
|
|
2966
|
+
|
|
2967
|
+
const serialized_signed = TxEnvelopeTempo.serialize(transaction, {
|
|
2968
|
+
signature: SignatureEnvelope.from({
|
|
2969
|
+
userAddress: root.address,
|
|
2970
|
+
inner: SignatureEnvelope.from(signature),
|
|
2971
|
+
type: 'keychain',
|
|
2972
|
+
}),
|
|
2973
|
+
})
|
|
2974
|
+
|
|
2975
|
+
const receipt = (await client
|
|
2976
|
+
.request({
|
|
2977
|
+
method: 'eth_sendRawTransactionSync',
|
|
2978
|
+
params: [serialized_signed],
|
|
2979
|
+
})
|
|
2980
|
+
.then((tx) => TransactionReceipt.fromRpc(tx as any)))!
|
|
2981
|
+
expect(receipt.status).toBe('success')
|
|
2982
|
+
|
|
2983
|
+
const response = await client
|
|
2984
|
+
.request({
|
|
2985
|
+
method: 'eth_getTransactionByHash',
|
|
2986
|
+
params: [receipt.transactionHash],
|
|
2987
|
+
})
|
|
2988
|
+
.then((tx) => Transaction.fromRpc(tx as any))
|
|
2989
|
+
if (!response) throw new Error()
|
|
2990
|
+
|
|
2991
|
+
expect(response.keyAuthorization?.isAdmin).toBeUndefined()
|
|
2992
|
+
expect(response.keyAuthorization?.account).toBeUndefined()
|
|
2993
|
+
},
|
|
2994
|
+
)
|
|
2665
2995
|
})
|
package/tempo/index.ts
CHANGED
|
@@ -36,53 +36,32 @@ export type {}
|
|
|
36
36
|
*/
|
|
37
37
|
export * as AuthorizationTempo from './AuthorizationTempo.js'
|
|
38
38
|
/**
|
|
39
|
-
* TIP-20 channel reserve constants and deterministic hashing utilities.
|
|
39
|
+
* TIP-20 channel reserve descriptor, constants, and deterministic hashing utilities.
|
|
40
40
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* Channel descriptors are emitted by `Channel.open` and then reused to settle,
|
|
42
|
+
* top up, close, request close, withdraw, or compute the channel ID. The channel
|
|
43
|
+
* reserve precompile exposes helper methods for channel identifiers, voucher sign
|
|
44
|
+
* payloads, and its EIP-712 domain separator. These utilities compute the same
|
|
45
|
+
* values locally when the chain id and channel fields are known.
|
|
44
46
|
*
|
|
45
47
|
* @example
|
|
46
48
|
* ```ts twoslash
|
|
47
49
|
* import { Channel } from 'ox/tempo'
|
|
48
50
|
*
|
|
49
|
-
* const
|
|
50
|
-
* authorizedSigner: '0x0000000000000000000000000000000000000000',
|
|
51
|
-
* chainId: 4217,
|
|
51
|
+
* const channel = Channel.from({
|
|
52
52
|
* expiringNonceHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
53
|
-
* operator: '0x0000000000000000000000000000000000000000',
|
|
54
53
|
* payee: '0x2222222222222222222222222222222222222222',
|
|
55
54
|
* payer: '0x1111111111111111111111111111111111111111',
|
|
56
55
|
* salt: '0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
57
56
|
* token: 1n,
|
|
58
57
|
* })
|
|
59
|
-
* ```
|
|
60
|
-
*
|
|
61
|
-
* @category Reference
|
|
62
|
-
*/
|
|
63
|
-
export * as Channel from './Channel.js'
|
|
64
|
-
/**
|
|
65
|
-
* TIP-20 channel reserve descriptor utilities.
|
|
66
58
|
*
|
|
67
|
-
*
|
|
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
|
-
* })
|
|
59
|
+
* const channelId = Channel.computeId(channel, { chainId: 4217 })
|
|
81
60
|
* ```
|
|
82
61
|
*
|
|
83
62
|
* @category Reference
|
|
84
63
|
*/
|
|
85
|
-
export * as
|
|
64
|
+
export * as Channel from './Channel.js'
|
|
86
65
|
/**
|
|
87
66
|
* Tempo key authorization utilities for provisioning and signing access keys.
|
|
88
67
|
*
|
package/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal */
|
|
2
|
-
export const version = '0.14.
|
|
2
|
+
export const version = '0.14.26'
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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,43 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,73 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,93 +0,0 @@
|
|
|
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
|
-
})
|