@turnkey/gas-station 0.2.0
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/LICENSE +201 -0
- package/README.md +726 -0
- package/dist/abi/gas-station.d.ts +546 -0
- package/dist/abi/gas-station.d.ts.map +1 -0
- package/dist/abi/gas-station.js +275 -0
- package/dist/abi/gas-station.js.map +1 -0
- package/dist/abi/gas-station.mjs +273 -0
- package/dist/abi/gas-station.mjs.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/config.mjs +51 -0
- package/dist/config.mjs.map +1 -0
- package/dist/gasStationClient.d.ts +71 -0
- package/dist/gasStationClient.d.ts.map +1 -0
- package/dist/gasStationClient.js +237 -0
- package/dist/gasStationClient.js.map +1 -0
- package/dist/gasStationClient.mjs +235 -0
- package/dist/gasStationClient.mjs.map +1 -0
- package/dist/gasStationUtils.d.ts +7069 -0
- package/dist/gasStationUtils.d.ts.map +1 -0
- package/dist/gasStationUtils.js +129 -0
- package/dist/gasStationUtils.js.map +1 -0
- package/dist/gasStationUtils.mjs +120 -0
- package/dist/gasStationUtils.mjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/dist/intentBuilder.d.ts +61 -0
- package/dist/intentBuilder.d.ts.map +1 -0
- package/dist/intentBuilder.js +153 -0
- package/dist/intentBuilder.js.map +1 -0
- package/dist/intentBuilder.mjs +151 -0
- package/dist/intentBuilder.mjs.map +1 -0
- package/dist/policyUtils.d.ts +271 -0
- package/dist/policyUtils.d.ts.map +1 -0
- package/dist/policyUtils.js +387 -0
- package/dist/policyUtils.js.map +1 -0
- package/dist/policyUtils.mjs +381 -0
- package/dist/policyUtils.mjs.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { encodeFunctionData } from 'viem';
|
|
2
|
+
import { ERC20_ABI } from './gasStationUtils.mjs';
|
|
3
|
+
|
|
4
|
+
class IntentBuilder {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.callData = "0x";
|
|
7
|
+
this.ethAmount = 0n;
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Set the target contract for this intent execution
|
|
12
|
+
*/
|
|
13
|
+
setTarget(contract) {
|
|
14
|
+
this.outputContract = contract;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Set the ETH value to send with this intent
|
|
19
|
+
*/
|
|
20
|
+
withValue(value) {
|
|
21
|
+
this.ethAmount = value;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Set a specific nonce (otherwise will be auto-fetched)
|
|
26
|
+
*/
|
|
27
|
+
withNonce(nonce) {
|
|
28
|
+
this.nonce = nonce;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Set an expiration deadline (unix timestamp in seconds)
|
|
33
|
+
* If not set, defaults to 1 hour from now
|
|
34
|
+
*/
|
|
35
|
+
withDeadline(deadline) {
|
|
36
|
+
this.deadline = deadline;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Set the call data directly (for pre-encoded function calls)
|
|
41
|
+
*/
|
|
42
|
+
withCallData(callData) {
|
|
43
|
+
this.callData = callData;
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Add a contract call to this intent
|
|
48
|
+
*/
|
|
49
|
+
callContract(params) {
|
|
50
|
+
this.outputContract = params.contract;
|
|
51
|
+
this.callData = encodeFunctionData({
|
|
52
|
+
abi: params.abi,
|
|
53
|
+
functionName: params.functionName,
|
|
54
|
+
args: params.args,
|
|
55
|
+
});
|
|
56
|
+
if (params.value) {
|
|
57
|
+
this.ethAmount = params.value;
|
|
58
|
+
}
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Convenience method for ERC20 transfers
|
|
63
|
+
*/
|
|
64
|
+
transferToken(token, to, amount) {
|
|
65
|
+
return this.callContract({
|
|
66
|
+
contract: token,
|
|
67
|
+
abi: ERC20_ABI,
|
|
68
|
+
functionName: "transfer",
|
|
69
|
+
args: [to, amount],
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Convenience method for ERC20 approvals
|
|
74
|
+
*/
|
|
75
|
+
approveToken(token, spender, amount) {
|
|
76
|
+
return this.callContract({
|
|
77
|
+
contract: token,
|
|
78
|
+
abi: ERC20_ABI,
|
|
79
|
+
functionName: "approve",
|
|
80
|
+
args: [spender, amount],
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convenience method for native ETH transfers
|
|
85
|
+
*/
|
|
86
|
+
transferETH(to, amount) {
|
|
87
|
+
this.outputContract = to;
|
|
88
|
+
this.callData = "0x";
|
|
89
|
+
this.ethAmount = amount;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Signs the execution intent using EIP-712
|
|
94
|
+
* Returns a complete ExecutionIntent ready for execution
|
|
95
|
+
*/
|
|
96
|
+
async sign(currentNonce) {
|
|
97
|
+
if (!this.outputContract) {
|
|
98
|
+
throw new Error("No target contract set. Use setTarget() or callContract()");
|
|
99
|
+
}
|
|
100
|
+
const nonce = this.nonce ?? currentNonce;
|
|
101
|
+
// Default deadline: 1 hour from now
|
|
102
|
+
const deadline = this.deadline ?? Math.floor(Date.now() / 1000) + 60 * 60;
|
|
103
|
+
// EIP-712 domain and types for gas station execution
|
|
104
|
+
const domain = {
|
|
105
|
+
name: "TKGasDelegate",
|
|
106
|
+
version: "1",
|
|
107
|
+
chainId: this.config.chainId,
|
|
108
|
+
verifyingContract: this.config.eoaAddress,
|
|
109
|
+
};
|
|
110
|
+
// Original: keccak256("Execution(uint128 nonce,uint32 deadline,address outputContract,uint256 ethAmount,bytes arguments)")
|
|
111
|
+
const types = {
|
|
112
|
+
Execution: [
|
|
113
|
+
{ name: "nonce", type: "uint128" },
|
|
114
|
+
{ name: "deadline", type: "uint32" },
|
|
115
|
+
{ name: "outputContract", type: "address" },
|
|
116
|
+
{ name: "ethAmount", type: "uint256" },
|
|
117
|
+
{ name: "arguments", type: "bytes" },
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
const message = {
|
|
121
|
+
nonce,
|
|
122
|
+
deadline,
|
|
123
|
+
outputContract: this.outputContract,
|
|
124
|
+
ethAmount: this.ethAmount,
|
|
125
|
+
arguments: this.callData,
|
|
126
|
+
};
|
|
127
|
+
const signature = await this.config.eoaWalletClient.signTypedData({
|
|
128
|
+
account: this.config.eoaWalletClient.account,
|
|
129
|
+
domain,
|
|
130
|
+
types,
|
|
131
|
+
primaryType: "Execution",
|
|
132
|
+
message,
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
nonce,
|
|
136
|
+
deadline,
|
|
137
|
+
outputContract: this.outputContract,
|
|
138
|
+
ethAmount: this.ethAmount,
|
|
139
|
+
callData: this.callData,
|
|
140
|
+
signature,
|
|
141
|
+
eoaAddress: this.config.eoaAddress,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Static factory method for quick intent creation
|
|
145
|
+
static create(config) {
|
|
146
|
+
return new IntentBuilder(config);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { IntentBuilder };
|
|
151
|
+
//# sourceMappingURL=intentBuilder.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intentBuilder.mjs","sources":["../src/intentBuilder.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import type { TurnkeyApiClient } from "@turnkey/sdk-server";
|
|
2
|
+
/**
|
|
3
|
+
* Build a Turnkey policy to restrict what EIP-712 intents an EOA can sign
|
|
4
|
+
* This protects at the signing layer - EOA cannot create signatures outside policy
|
|
5
|
+
*
|
|
6
|
+
* @param config - Policy configuration
|
|
7
|
+
* @param config.organizationId - Turnkey organization ID
|
|
8
|
+
* @param config.eoaUserId - Turnkey user ID for the EOA (primary approver)
|
|
9
|
+
* @param config.additionalApprovers - Optional additional user IDs that must also approve (creates AND condition)
|
|
10
|
+
* @param config.customConsensus - Optional custom consensus expression (overrides eoaUserId and additionalApprovers)
|
|
11
|
+
* @param config.restrictions - Signing restrictions
|
|
12
|
+
* @param config.restrictions.allowedContracts - Whitelist of contract addresses EOA can sign intents for
|
|
13
|
+
* @param config.restrictions.disallowEthTransfer - Whether to disallow ETH transfers (if true, ethAmount must be 0)
|
|
14
|
+
* @param config.policyName - Optional policy name
|
|
15
|
+
* @returns Policy object ready to submit to Turnkey createPolicy API
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Simple: single user approval, token-only transfers
|
|
19
|
+
* const policy = buildIntentSigningPolicy({
|
|
20
|
+
* organizationId: "org-123",
|
|
21
|
+
* eoaUserId: "user-456",
|
|
22
|
+
* restrictions: {
|
|
23
|
+
* allowedContracts: ["0x833...USDC", "0x6B1...DAI"],
|
|
24
|
+
* disallowEthTransfer: true,
|
|
25
|
+
* },
|
|
26
|
+
* policyName: "Stablecoin Only",
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Resulting policy:
|
|
30
|
+
* {
|
|
31
|
+
* organizationId: "org-123",
|
|
32
|
+
* policyName: "Stablecoin Only",
|
|
33
|
+
* effect: "EFFECT_ALLOW",
|
|
34
|
+
* consensus: "approvers.any(user, user.id == 'user-456')",
|
|
35
|
+
* condition: "activity.resource == 'PRIVATE_KEY' && activity.action == 'SIGN' && " +
|
|
36
|
+
* "eth.eip_712.primary_type == 'Execution' && " +
|
|
37
|
+
* "(eth.eip_712.message['outputContract'] == '0x833...usdc' || " +
|
|
38
|
+
* "eth.eip_712.message['outputContract'] == '0x6b1...dai') && " +
|
|
39
|
+
* "eth.eip_712.message['ethAmount'] == '0'",
|
|
40
|
+
* notes: "Restricts which EIP-712 intents the EOA can sign for gas station execution"
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Multi-approval: EOA AND backup user must both approve
|
|
45
|
+
* const policy = buildIntentSigningPolicy({
|
|
46
|
+
* organizationId: "org-123",
|
|
47
|
+
* eoaUserId: "user-456",
|
|
48
|
+
* additionalApprovers: ["backup-user-789"],
|
|
49
|
+
* restrictions: {
|
|
50
|
+
* allowedContracts: ["0x833...USDC"],
|
|
51
|
+
* disallowEthTransfer: true,
|
|
52
|
+
* },
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* // Resulting policy:
|
|
56
|
+
* {
|
|
57
|
+
* organizationId: "org-123",
|
|
58
|
+
* policyName: "Gas Station Intent Signing Policy",
|
|
59
|
+
* effect: "EFFECT_ALLOW",
|
|
60
|
+
* consensus: "approvers.any(user, user.id == 'user-456') && " +
|
|
61
|
+
* "approvers.any(user, user.id == 'backup-user-789')",
|
|
62
|
+
* condition: "activity.resource == 'PRIVATE_KEY' && activity.action == 'SIGN' && " +
|
|
63
|
+
* "eth.eip_712.primary_type == 'Execution' && " +
|
|
64
|
+
* "(eth.eip_712.message['outputContract'] == '0x833...usdc') && " +
|
|
65
|
+
* "eth.eip_712.message['ethAmount'] == '0'",
|
|
66
|
+
* notes: "Restricts which EIP-712 intents the EOA can sign for gas station execution"
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Advanced: custom consensus expression
|
|
71
|
+
* const policy = buildIntentSigningPolicy({
|
|
72
|
+
* organizationId: "org-123",
|
|
73
|
+
* eoaUserId: "user-456",
|
|
74
|
+
* customConsensus: "approvers.count() >= 2",
|
|
75
|
+
* restrictions: {
|
|
76
|
+
* disallowEthTransfer: false,
|
|
77
|
+
* },
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* await turnkeyClient.apiClient().createPolicy(policy);
|
|
81
|
+
*/
|
|
82
|
+
export declare function buildIntentSigningPolicy(config: {
|
|
83
|
+
organizationId: string;
|
|
84
|
+
eoaUserId: string;
|
|
85
|
+
additionalApprovers?: string[];
|
|
86
|
+
customConsensus?: string;
|
|
87
|
+
restrictions?: {
|
|
88
|
+
allowedContracts?: `0x${string}`[];
|
|
89
|
+
disallowEthTransfer?: boolean;
|
|
90
|
+
};
|
|
91
|
+
policyName?: string;
|
|
92
|
+
}): {
|
|
93
|
+
organizationId: string;
|
|
94
|
+
policyName: string;
|
|
95
|
+
effect: "EFFECT_ALLOW";
|
|
96
|
+
consensus: string;
|
|
97
|
+
condition: string;
|
|
98
|
+
notes: string;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Build a Turnkey policy to restrict what the paymaster can execute on-chain.
|
|
102
|
+
* This protects at the execution layer - paymaster cannot submit transactions outside policy.
|
|
103
|
+
*
|
|
104
|
+
* This function uses Turnkey's Smart Contract Interface feature to parse the
|
|
105
|
+
* execute(address _targetEoA, address _to, uint256 ethAmount, bytes _data) ABI.
|
|
106
|
+
* Before using this function, ensure the Gas Station ABI is uploaded via
|
|
107
|
+
* ensureGasStationInterface() - this is typically handled automatically.
|
|
108
|
+
*
|
|
109
|
+
* @param config - Policy configuration
|
|
110
|
+
* @param config.organizationId - Turnkey organization ID
|
|
111
|
+
* @param config.paymasterUserId - Turnkey user ID for the paymaster (primary approver)
|
|
112
|
+
* @param config.additionalApprovers - Optional additional user IDs that can approve (creates OR condition)
|
|
113
|
+
* @param config.customConsensus - Optional custom consensus expression (overrides paymasterUserId and additionalApprovers)
|
|
114
|
+
* @param config.executionContractAddress - Gas station execution contract address
|
|
115
|
+
* @param config.restrictions - Execution restrictions
|
|
116
|
+
* @param config.restrictions.allowedEOAs - Whitelist of EOA addresses paymaster can execute for
|
|
117
|
+
* @param config.restrictions.allowedContracts - Whitelist of output contract addresses (target contracts)
|
|
118
|
+
* @param config.restrictions.maxEthAmount - Maximum ETH amount in wei that can be transferred
|
|
119
|
+
* @param config.restrictions.maxGasPrice - Maximum gas price in wei
|
|
120
|
+
* @param config.restrictions.maxGasLimit - Maximum gas limit
|
|
121
|
+
* @param config.policyName - Optional policy name
|
|
122
|
+
* @returns Policy object ready to submit to Turnkey createPolicy API
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // Simple: single paymaster approval with ETH amount limit
|
|
126
|
+
* const policy = buildPaymasterExecutionPolicy({
|
|
127
|
+
* organizationId: "org-paymaster",
|
|
128
|
+
* paymasterUserId: "paymaster-user-123",
|
|
129
|
+
* executionContractAddress: "0x576A4D741b96996cc93B4919a04c16545734481f",
|
|
130
|
+
* restrictions: {
|
|
131
|
+
* allowedEOAs: ["0xAli...ce", "0xBob...by"],
|
|
132
|
+
* allowedContracts: ["0x833...USDC", "0x6B1...DAI"],
|
|
133
|
+
* maxEthAmount: parseEther("0.1"), // Max 0.1 ETH per transaction
|
|
134
|
+
* maxGasPrice: parseGwei("50"),
|
|
135
|
+
* maxGasLimit: 500000n,
|
|
136
|
+
* },
|
|
137
|
+
* policyName: "Paymaster Protection",
|
|
138
|
+
* });
|
|
139
|
+
*
|
|
140
|
+
* // Resulting policy (uses ABI parsing):
|
|
141
|
+
* {
|
|
142
|
+
* organizationId: "org-paymaster",
|
|
143
|
+
* policyName: "Paymaster Protection",
|
|
144
|
+
* effect: "EFFECT_ALLOW",
|
|
145
|
+
* consensus: "approvers.any(user, user.id == 'paymaster-user-123')",
|
|
146
|
+
* condition: "activity.resource == 'PRIVATE_KEY' && activity.action == 'SIGN' && " +
|
|
147
|
+
* "eth.tx.to == '0x576a...481f' && " +
|
|
148
|
+
* "(eth.tx.contract_call_args['_to'] == '0x833...usdc' || " +
|
|
149
|
+
* "eth.tx.contract_call_args['_to'] == '0x6b1...dai') && " +
|
|
150
|
+
* "(eth.tx.contract_call_args['_targetEoA'] == '0xali...ce' || " +
|
|
151
|
+
* "eth.tx.contract_call_args['_targetEoA'] == '0xbob...by') && " +
|
|
152
|
+
* "eth.tx.contract_call_args['ethAmount'] <= 100000000000000000 && " +
|
|
153
|
+
* "eth.tx.gasPrice <= 50000000000 && eth.tx.gas <= 500000",
|
|
154
|
+
* notes: "Restricts which execute() transactions the paymaster can submit on-chain"
|
|
155
|
+
* }
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* // Multi-user: primary paymaster OR backup can approve
|
|
159
|
+
* const policy = buildPaymasterExecutionPolicy({
|
|
160
|
+
* organizationId: "org-paymaster",
|
|
161
|
+
* paymasterUserId: "paymaster-user-123",
|
|
162
|
+
* additionalApprovers: ["backup-paymaster-456"],
|
|
163
|
+
* executionContractAddress: "0x576A4D741b96996cc93B4919a04c16545734481f",
|
|
164
|
+
* restrictions: {
|
|
165
|
+
* allowedEOAs: ["0xAli...ce"],
|
|
166
|
+
* maxEthAmount: parseEther("1"), // Max 1 ETH
|
|
167
|
+
* maxGasPrice: parseGwei("100"),
|
|
168
|
+
* },
|
|
169
|
+
* });
|
|
170
|
+
*
|
|
171
|
+
* // Resulting policy (uses ABI parsing):
|
|
172
|
+
* {
|
|
173
|
+
* organizationId: "org-paymaster",
|
|
174
|
+
* policyName: "Gas Station Paymaster Execution Policy",
|
|
175
|
+
* effect: "EFFECT_ALLOW",
|
|
176
|
+
* consensus: "approvers.any(user, user.id == 'paymaster-user-123' || " +
|
|
177
|
+
* "user.id == 'backup-paymaster-456')",
|
|
178
|
+
* condition: "activity.resource == 'PRIVATE_KEY' && activity.action == 'SIGN' && " +
|
|
179
|
+
* "eth.tx.to == '0x576a...481f' && " +
|
|
180
|
+
* "(eth.tx.contract_call_args['_targetEoA'] == '0xali...ce') && " +
|
|
181
|
+
* "eth.tx.contract_call_args['ethAmount'] <= 1000000000000000000 && " +
|
|
182
|
+
* "eth.tx.gasPrice <= 100000000000",
|
|
183
|
+
* notes: "Restricts which execute() transactions the paymaster can submit on-chain"
|
|
184
|
+
* }
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* // Advanced: require multiple approvals
|
|
188
|
+
* const policy = buildPaymasterExecutionPolicy({
|
|
189
|
+
* organizationId: "org-paymaster",
|
|
190
|
+
* paymasterUserId: "paymaster-user-123",
|
|
191
|
+
* customConsensus: "approvers.count() >= 2",
|
|
192
|
+
* executionContractAddress: "0x576A4D741b96996cc93B4919a04c16545734481f",
|
|
193
|
+
* restrictions: { ... },
|
|
194
|
+
* });
|
|
195
|
+
*
|
|
196
|
+
* await turnkeyClient.apiClient().createPolicy(policy);
|
|
197
|
+
*/
|
|
198
|
+
export declare function buildPaymasterExecutionPolicy(config: {
|
|
199
|
+
organizationId: string;
|
|
200
|
+
paymasterUserId: string;
|
|
201
|
+
additionalApprovers?: string[];
|
|
202
|
+
customConsensus?: string;
|
|
203
|
+
executionContractAddress: `0x${string}`;
|
|
204
|
+
restrictions?: {
|
|
205
|
+
allowedEOAs?: `0x${string}`[];
|
|
206
|
+
allowedContracts?: `0x${string}`[];
|
|
207
|
+
maxEthAmount?: bigint;
|
|
208
|
+
maxGasPrice?: bigint;
|
|
209
|
+
maxGasLimit?: bigint;
|
|
210
|
+
};
|
|
211
|
+
policyName?: string;
|
|
212
|
+
}): {
|
|
213
|
+
organizationId: string;
|
|
214
|
+
policyName: string;
|
|
215
|
+
effect: "EFFECT_ALLOW";
|
|
216
|
+
consensus: string;
|
|
217
|
+
condition: string;
|
|
218
|
+
notes: string;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Retrieves an existing smart contract interface for the given contract address.
|
|
222
|
+
* Returns the interface ID if found, undefined otherwise.
|
|
223
|
+
*/
|
|
224
|
+
export declare function getSmartContractInterface({ client, organizationId, contractAddress, }: {
|
|
225
|
+
client: TurnkeyApiClient;
|
|
226
|
+
organizationId: string;
|
|
227
|
+
contractAddress: `0x${string}`;
|
|
228
|
+
}): Promise<string | undefined>;
|
|
229
|
+
/**
|
|
230
|
+
* Uploads the Gas Station ABI to Turnkey as a Smart Contract Interface.
|
|
231
|
+
* Returns the newly created interface ID.
|
|
232
|
+
*/
|
|
233
|
+
export declare function uploadGasStationInterface({ client, organizationId, contractAddress, label, chainName, }: {
|
|
234
|
+
client: TurnkeyApiClient;
|
|
235
|
+
organizationId: string;
|
|
236
|
+
contractAddress: `0x${string}`;
|
|
237
|
+
label?: string;
|
|
238
|
+
chainName?: string;
|
|
239
|
+
}): Promise<string>;
|
|
240
|
+
/**
|
|
241
|
+
* Ensures that a Gas Station ABI is registered with Turnkey for the given contract.
|
|
242
|
+
* Checks if an interface already exists; if not, uploads it automatically.
|
|
243
|
+
* Returns the interface ID (existing or newly created).
|
|
244
|
+
*
|
|
245
|
+
* This function is called automatically by policy builders to enable ABI-based
|
|
246
|
+
* policy conditions that can directly access and compare function arguments.
|
|
247
|
+
*
|
|
248
|
+
* @param client - Turnkey API client (from turnkeySDK.apiClient())
|
|
249
|
+
* @param organizationId - Turnkey organization ID
|
|
250
|
+
* @param contractAddress - Gas station contract address
|
|
251
|
+
* @param label - Optional custom label for the interface
|
|
252
|
+
* @param chainName - Optional chain name for labeling (e.g., "Base Mainnet")
|
|
253
|
+
* @returns The smart contract interface ID
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* const interfaceId = await ensureGasStationInterface(
|
|
257
|
+
* turnkeyClient.apiClient(),
|
|
258
|
+
* "org-123",
|
|
259
|
+
* "0x576A4D741b96996cc93B4919a04c16545734481f",
|
|
260
|
+
* undefined,
|
|
261
|
+
* "Base Sepolia"
|
|
262
|
+
* );
|
|
263
|
+
*/
|
|
264
|
+
export declare function ensureGasStationInterface({ client, organizationId, contractAddress, label, chainName, }: {
|
|
265
|
+
client: TurnkeyApiClient;
|
|
266
|
+
organizationId: string;
|
|
267
|
+
contractAddress: `0x${string}`;
|
|
268
|
+
label?: string;
|
|
269
|
+
chainName?: string;
|
|
270
|
+
}): Promise<string>;
|
|
271
|
+
//# sourceMappingURL=policyUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policyUtils.d.ts","sourceRoot":"","sources":["../src/policyUtils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE;QACb,gBAAgB,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;QACnC,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;;;;;;;EAwDA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,KAAK,MAAM,EAAE,CAAC;IACxC,YAAY,CAAC,EAAE;QACb,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;QAC9B,gBAAgB,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;QACnC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;;;;;;;EAmFA;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,MAAM,EACN,cAAc,EACd,eAAe,GAChB,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;CAChC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoB9B;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,MAAM,EACN,cAAc,EACd,eAAe,EACf,KAAK,EACL,SAAS,GACV,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,MAAM,EACN,cAAc,EACd,eAAe,EACf,KAAK,EACL,SAAS,GACV,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlB"}
|