@tonappchain/sdk 0.7.3-rc8 → 0.8.0-aa-alpha-test
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/dist/artifacts/dev/tac/internal/artifacts/contracts/interfaces/ICrossChainLayer.sol/ICrossChainLayer.json +0 -7
- package/dist/artifacts/dev/tac/internal/artifacts/contracts/interfaces/ISettings.sol/ISettings.json +0 -7
- package/dist/artifacts/dev/tac/internal/artifacts/contracts/interfaces/ITokenUtils.sol/ITokenUtils.json +0 -7
- package/dist/artifacts/dev/tac/internal/artifacts/contracts/smart-account/interfaces/ISAFactory.sol/ISAFactory.json +0 -7
- package/dist/artifacts/dev/tac/internal/typechain-types/contracts/interfaces/ICrossChainLayer.d.ts +1 -5
- package/dist/artifacts/dev/tac/internal/typechain-types/contracts/interfaces/ISettings.d.ts +1 -5
- package/dist/artifacts/dev/tac/internal/typechain-types/contracts/interfaces/ITokenUtils.d.ts +1 -5
- package/dist/artifacts/dev/tac/internal/typechain-types/contracts/smart-account/interfaces/ISAFactory.d.ts +1 -5
- package/dist/artifacts/dev/ton/internal/build/Settings.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/wrappers/Settings.d.ts +1 -0
- package/dist/artifacts/dev/ton/internal/wrappers/Settings.js +11 -7
- package/dist/artifacts/index.d.ts +5 -3
- package/dist/artifacts/index.js +6 -3
- package/dist/artifacts/mainnet/tac/internal/artifacts/contracts/interfaces/ICrossChainLayer.sol/ICrossChainLayer.json +0 -7
- package/dist/artifacts/mainnet/tac/internal/artifacts/contracts/interfaces/ISettings.sol/ISettings.json +0 -7
- package/dist/artifacts/mainnet/tac/internal/artifacts/contracts/interfaces/ITokenUtils.sol/ITokenUtils.json +0 -7
- package/dist/artifacts/mainnet/tac/internal/artifacts/contracts/smart-account/interfaces/ISAFactory.sol/ISAFactory.json +0 -7
- package/dist/artifacts/mainnet/tac/internal/typechain-types/contracts/interfaces/ICrossChainLayer.d.ts +1 -5
- package/dist/artifacts/mainnet/tac/internal/typechain-types/contracts/interfaces/ISettings.d.ts +1 -5
- package/dist/artifacts/mainnet/tac/internal/typechain-types/contracts/interfaces/ITokenUtils.d.ts +1 -5
- package/dist/artifacts/mainnet/tac/internal/typechain-types/contracts/smart-account/interfaces/ISAFactory.d.ts +1 -5
- package/dist/artifacts/mainnet/ton/internal/build/CrossChainLayer.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/Executor.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/JettonMinter.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/JettonProxy.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/JettonWallet.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/NFTCollection.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/NFTItem.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/NFTProxy.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/Settings.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/wrappers/CrossChainLayer.d.ts +65 -6
- package/dist/artifacts/mainnet/ton/internal/wrappers/CrossChainLayer.js +169 -18
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonMinter.d.ts +4 -2
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonMinter.js +5 -3
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonProxy.d.ts +9 -0
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonProxy.js +11 -2
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonWallet.d.ts +7 -0
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonWallet.js +9 -2
- package/dist/artifacts/mainnet/ton/internal/wrappers/NFTCollection.d.ts +11 -1
- package/dist/artifacts/mainnet/ton/internal/wrappers/NFTCollection.js +17 -5
- package/dist/artifacts/mainnet/ton/internal/wrappers/NFTItem.d.ts +9 -1
- package/dist/artifacts/mainnet/ton/internal/wrappers/NFTItem.js +15 -5
- package/dist/artifacts/mainnet/ton/internal/wrappers/NFTProxy.d.ts +9 -1
- package/dist/artifacts/mainnet/ton/internal/wrappers/NFTProxy.js +16 -6
- package/dist/artifacts/mainnet/ton/internal/wrappers/Settings.d.ts +2 -0
- package/dist/artifacts/mainnet/ton/internal/wrappers/Settings.js +11 -6
- package/dist/artifacts/mainnet/ton/internal/wrappers/utils/CrossChainLayerPayload.d.ts +10 -0
- package/dist/artifacts/mainnet/ton/internal/wrappers/utils/CrossChainLayerPayload.js +24 -0
- package/dist/artifacts/mainnet/ton/internal/wrappers/utils/MerkleRoots.d.ts +2 -1
- package/dist/artifacts/mainnet/ton/internal/wrappers/utils/MerkleRoots.js +9 -1
- package/dist/artifacts/testnet/tac/internal/artifacts/contracts/interfaces/ICrossChainLayer.sol/ICrossChainLayer.json +0 -7
- package/dist/artifacts/testnet/tac/internal/artifacts/contracts/interfaces/ISettings.sol/ISettings.json +0 -7
- package/dist/artifacts/testnet/tac/internal/artifacts/contracts/interfaces/ITokenUtils.sol/ITokenUtils.json +0 -7
- package/dist/artifacts/testnet/tac/internal/artifacts/contracts/smart-account/interfaces/ISAFactory.sol/ISAFactory.json +0 -7
- package/dist/artifacts/testnet/tac/internal/typechain-types/contracts/interfaces/ICrossChainLayer.d.ts +1 -5
- package/dist/artifacts/testnet/tac/internal/typechain-types/contracts/interfaces/ISettings.d.ts +1 -5
- package/dist/artifacts/testnet/tac/internal/typechain-types/contracts/interfaces/ITokenUtils.d.ts +1 -5
- package/dist/artifacts/testnet/tac/internal/typechain-types/contracts/smart-account/interfaces/ISAFactory.d.ts +1 -5
- package/dist/artifacts/testnet/ton/internal/build/Settings.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/wrappers/Settings.d.ts +1 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/Settings.js +11 -7
- package/dist/src/accountAbstraction/BaseAccountAPI.d.ts +62 -0
- package/dist/src/accountAbstraction/BaseAccountAPI.js +163 -0
- package/dist/src/accountAbstraction/Ed25519.d.ts +47 -0
- package/dist/src/accountAbstraction/Ed25519.js +100 -0
- package/dist/src/accountAbstraction/HttpRpcClient.d.ts +26 -0
- package/dist/src/accountAbstraction/HttpRpcClient.js +45 -0
- package/dist/src/accountAbstraction/PaymasterAPI.d.ts +21 -0
- package/dist/src/accountAbstraction/PaymasterAPI.js +18 -0
- package/dist/src/accountAbstraction/Permit2.d.ts +37 -0
- package/dist/src/accountAbstraction/Permit2.js +41 -0
- package/dist/src/accountAbstraction/PermitFlow.d.ts +43 -0
- package/dist/src/accountAbstraction/PermitFlow.js +80 -0
- package/dist/src/accountAbstraction/TacAccountAPI.d.ts +53 -0
- package/dist/src/accountAbstraction/TacAccountAPI.js +84 -0
- package/dist/src/accountAbstraction/TacAccountSdk.d.ts +101 -0
- package/dist/src/accountAbstraction/TacAccountSdk.js +163 -0
- package/dist/src/accountAbstraction/TacERC20PaymasterAPI.d.ts +59 -0
- package/dist/src/accountAbstraction/TacERC20PaymasterAPI.js +88 -0
- package/dist/src/accountAbstraction/TransactionDetailsForUserOp.d.ts +10 -0
- package/dist/src/accountAbstraction/TransactionDetailsForUserOp.js +2 -0
- package/dist/src/accountAbstraction/abi.d.ts +3 -0
- package/dist/src/accountAbstraction/abi.js +32 -0
- package/dist/src/accountAbstraction/index.d.ts +24 -0
- package/dist/src/accountAbstraction/index.js +44 -0
- package/dist/src/accountAbstraction/internal/entryPointAbi.d.ts +1 -0
- package/dist/src/accountAbstraction/internal/entryPointAbi.js +16 -0
- package/dist/src/accountAbstraction/internal/userOp.d.ts +54 -0
- package/dist/src/accountAbstraction/internal/userOp.js +72 -0
- package/dist/src/accountAbstraction/networks.d.ts +22 -0
- package/dist/src/accountAbstraction/networks.js +19 -0
- package/dist/src/accountAbstraction/signer.d.ts +12 -0
- package/dist/src/accountAbstraction/signer.js +14 -0
- package/dist/src/adapters/RetryableContractOpener.js +5 -2
- package/dist/src/adapters/ToncenterV3Indexer.js +1 -1
- package/dist/src/assets/AssetCache.d.ts +4 -4
- package/dist/src/assets/AssetCache.js +11 -6
- package/dist/src/assets/AssetFactory.js +2 -2
- package/dist/src/errors/index.d.ts +1 -1
- package/dist/src/errors/index.js +2 -1
- package/dist/src/errors/instances.d.ts +1 -0
- package/dist/src/errors/instances.js +3 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +4 -1
- package/dist/src/interfaces/IConfiguration.d.ts +2 -2
- package/dist/src/sdk/Artifacts.d.ts +3 -0
- package/dist/src/sdk/Artifacts.js +17 -0
- package/dist/src/sdk/Configuration.d.ts +4 -4
- package/dist/src/sdk/Configuration.js +3 -3
- package/dist/src/sdk/Consts.d.ts +0 -1
- package/dist/src/sdk/Consts.js +1 -2
- package/dist/src/sdk/LiteSequencerClient.js +2 -1
- package/dist/src/sdk/StartTracking.js +2 -2
- package/dist/src/sdk/TACTransactionManager.js +5 -5
- package/dist/src/sdk/TONTransactionManager.js +23 -21
- package/dist/src/sdk/TacExplorerClient.js +4 -3
- package/dist/src/sdk/TacSdk.js +2 -15
- package/dist/src/sdk/TxFinalizer.js +1 -1
- package/dist/src/sdk/Utils.js +37 -4
- package/dist/src/structs/Struct.d.ts +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Higher-level helper for paymaster Mode 1 — TRANSFER_VIA_PERMIT.
|
|
3
|
+
//
|
|
4
|
+
// This mode needs a *double-signing* dance: both userOp.signature AND the inner signature
|
|
5
|
+
// inside paymasterData depend on userOpHash, which itself depends on paymasterAndData (which
|
|
6
|
+
// contains the inner signature). The flow:
|
|
7
|
+
//
|
|
8
|
+
// 1. Compute permit + permitHash.
|
|
9
|
+
// 2. Build paymasterData with a placeholder inner sig (96 zero bytes).
|
|
10
|
+
// 3. userOpHash_r1 = getUserOpHash(op with placeholder).
|
|
11
|
+
// 4. sign Ed25519 over `userOpHash_r1 || permitHash` -> (r1, s1).
|
|
12
|
+
// 5. paymasterData.innerSig = r1 ‖ s1 ‖ userOpHash_r1.
|
|
13
|
+
// 6. userOpHash_r2 = getUserOpHash(final op).
|
|
14
|
+
// 7. sign Ed25519 over `userOpHash_r2 || permitHash` -> (r2, s2).
|
|
15
|
+
// 8. userOp.signature = r2 ‖ s2 ‖ permitHash.
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.buildSignedUserOpWithPermit = buildSignedUserOpWithPermit;
|
|
18
|
+
exports.buildSignedUserOpWithPermitTonConnect = buildSignedUserOpWithPermitTonConnect;
|
|
19
|
+
const ethers_1 = require("ethers");
|
|
20
|
+
const Ed25519_1 = require("./Ed25519");
|
|
21
|
+
const entryPointAbi_1 = require("./internal/entryPointAbi");
|
|
22
|
+
const userOp_1 = require("./internal/userOp");
|
|
23
|
+
const Permit2_1 = require("./Permit2");
|
|
24
|
+
const TacERC20PaymasterAPI_1 = require("./TacERC20PaymasterAPI");
|
|
25
|
+
const DEFAULT_PM_GAS = 100000;
|
|
26
|
+
const PLACEHOLDER_INNER_SIG = '0x' + '00'.repeat(96);
|
|
27
|
+
/**
|
|
28
|
+
* Build a fully-signed UserOp paying gas via TacERC20Paymaster's TRANSFER_VIA_PERMIT mode.
|
|
29
|
+
* Performs the two-round double-sign; the EntryPoint (for userOpHash) is derived from the
|
|
30
|
+
* accountAPI's entryPointAddress + provider.
|
|
31
|
+
*/
|
|
32
|
+
async function buildSignedUserOpWithPermit(input) {
|
|
33
|
+
const { accountAPI, paymaster, permitInput, ed25519Signer, txDetails } = input;
|
|
34
|
+
const pmVerifGas = input.paymasterVerificationGasLimit ?? DEFAULT_PM_GAS;
|
|
35
|
+
const pmPostOpGas = input.paymasterPostOpGasLimit ?? DEFAULT_PM_GAS;
|
|
36
|
+
const entryPoint = new ethers_1.Contract(accountAPI.entryPointAddress, entryPointAbi_1.IEntryPointABI, accountAPI.provider);
|
|
37
|
+
const { permit, permitHash } = (0, Permit2_1.buildPermitMessage)(permitInput);
|
|
38
|
+
// Round 1 — placeholder inner signature.
|
|
39
|
+
const userOp = await accountAPI.createUnsignedUserOp(txDetails);
|
|
40
|
+
userOp.paymaster = paymaster;
|
|
41
|
+
userOp.paymasterVerificationGasLimit = pmVerifGas;
|
|
42
|
+
userOp.paymasterPostOpGasLimit = pmPostOpGas;
|
|
43
|
+
userOp.paymasterData = (0, ethers_1.concat)([
|
|
44
|
+
(0, TacERC20PaymasterAPI_1.packModeByte)(TacERC20PaymasterAPI_1.TacPaymasterMode.TRANSFER_VIA_PERMIT),
|
|
45
|
+
(0, Permit2_1.packPermitData)(permit, PLACEHOLDER_INNER_SIG),
|
|
46
|
+
]);
|
|
47
|
+
const userOpHashR1 = await entryPoint.getUserOpHash.staticCall((0, userOp_1.packUserOp)(userOp));
|
|
48
|
+
const sigR1 = await ed25519Signer((0, Ed25519_1.buildPermitBinding)(userOpHashR1, permitHash));
|
|
49
|
+
// Round 2 — final inner signature bound to userOpHash_r1.
|
|
50
|
+
const innerSig = (0, Ed25519_1.packPermit2InnerSignature)(sigR1, userOpHashR1);
|
|
51
|
+
userOp.paymasterData = (0, ethers_1.concat)([(0, TacERC20PaymasterAPI_1.packModeByte)(TacERC20PaymasterAPI_1.TacPaymasterMode.TRANSFER_VIA_PERMIT), (0, Permit2_1.packPermitData)(permit, innerSig)]);
|
|
52
|
+
const userOpHashR2 = await entryPoint.getUserOpHash.staticCall((0, userOp_1.packUserOp)(userOp));
|
|
53
|
+
const sigR2 = await ed25519Signer((0, Ed25519_1.buildPermitBinding)(userOpHashR2, permitHash));
|
|
54
|
+
userOp.signature = (0, Ed25519_1.packPermitBoundUserOpSignature)(sigR2, permitHash);
|
|
55
|
+
return userOp;
|
|
56
|
+
}
|
|
57
|
+
/** TonConnect-wallet variant of {@link buildSignedUserOpWithPermit}. */
|
|
58
|
+
async function buildSignedUserOpWithPermitTonConnect(input) {
|
|
59
|
+
const { accountAPI, paymaster, permitInput, tonConnectSigner, txDetails } = input;
|
|
60
|
+
const pmVerifGas = input.paymasterVerificationGasLimit ?? DEFAULT_PM_GAS;
|
|
61
|
+
const pmPostOpGas = input.paymasterPostOpGasLimit ?? DEFAULT_PM_GAS;
|
|
62
|
+
const entryPoint = new ethers_1.Contract(accountAPI.entryPointAddress, entryPointAbi_1.IEntryPointABI, accountAPI.provider);
|
|
63
|
+
const { permit, permitHash } = (0, Permit2_1.buildPermitMessage)(permitInput);
|
|
64
|
+
const userOp = await accountAPI.createUnsignedUserOp(txDetails);
|
|
65
|
+
userOp.paymaster = paymaster;
|
|
66
|
+
userOp.paymasterVerificationGasLimit = pmVerifGas;
|
|
67
|
+
userOp.paymasterPostOpGasLimit = pmPostOpGas;
|
|
68
|
+
userOp.paymasterData = (0, ethers_1.concat)([
|
|
69
|
+
(0, TacERC20PaymasterAPI_1.packModeByte)(TacERC20PaymasterAPI_1.TacPaymasterMode.TRANSFER_VIA_PERMIT),
|
|
70
|
+
(0, Permit2_1.packPermitData)(permit, PLACEHOLDER_INNER_SIG),
|
|
71
|
+
]);
|
|
72
|
+
const userOpHashR1 = await entryPoint.getUserOpHash.staticCall((0, userOp_1.packUserOp)(userOp));
|
|
73
|
+
const partsR1 = await tonConnectSigner((0, Ed25519_1.buildPermitBinding)(userOpHashR1, permitHash));
|
|
74
|
+
const innerSig = (0, Ed25519_1.packTonConnectPermit2InnerSignature)(partsR1, userOpHashR1);
|
|
75
|
+
userOp.paymasterData = (0, ethers_1.concat)([(0, TacERC20PaymasterAPI_1.packModeByte)(TacERC20PaymasterAPI_1.TacPaymasterMode.TRANSFER_VIA_PERMIT), (0, Permit2_1.packPermitData)(permit, innerSig)]);
|
|
76
|
+
const userOpHashR2 = await entryPoint.getUserOpHash.staticCall((0, userOp_1.packUserOp)(userOp));
|
|
77
|
+
const partsR2 = await tonConnectSigner((0, Ed25519_1.buildPermitBinding)(userOpHashR2, permitHash));
|
|
78
|
+
userOp.signature = (0, Ed25519_1.packTonConnectUserOpSignature)(partsR2, permitHash);
|
|
79
|
+
return userOp;
|
|
80
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { BigNumberish } from 'ethers';
|
|
2
|
+
import { BaseAccountAPI, BaseApiParams } from './BaseAccountAPI';
|
|
3
|
+
import { Ed25519Signer, TonConnectSigner } from './Ed25519';
|
|
4
|
+
import { FactoryParams } from './internal/userOp';
|
|
5
|
+
/**
|
|
6
|
+
* Constructor params for {@link TacAccountAPI}. Exactly ONE of `signer` or
|
|
7
|
+
* `tonConnectSigner` must be provided.
|
|
8
|
+
*
|
|
9
|
+
* @param publicKey Ed25519 public key as 32-byte hex (0x-prefixed). The
|
|
10
|
+
* deterministic AA address is derived from this key alone.
|
|
11
|
+
* @param signer raw Ed25519 signer (returns `(r, s)` over a 32-byte message).
|
|
12
|
+
* @param tonConnectSigner TonConnect-wallet signer.
|
|
13
|
+
* @param factoryAddress deployed `TacAccountFactory` address.
|
|
14
|
+
*/
|
|
15
|
+
export interface TacAccountApiParams extends BaseApiParams {
|
|
16
|
+
publicKey: string;
|
|
17
|
+
signer?: Ed25519Signer;
|
|
18
|
+
tonConnectSigner?: TonConnectSigner;
|
|
19
|
+
factoryAddress: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* BaseAccountAPI implementation for TAC's Ed25519 + beacon-proxy accounts.
|
|
23
|
+
*
|
|
24
|
+
* - account address is derived from the Ed25519 public key only
|
|
25
|
+
* (`salt = keccak256(publicKey)` inside the factory)
|
|
26
|
+
* - factoryData is `TacAccountFactory.getOrCreateAccount(publicKey)`
|
|
27
|
+
* - signature is Ed25519 in the 64-byte raw format (this class), or the 96-byte /
|
|
28
|
+
* TonConnect formats via {@link buildSignedUserOpWithPermit} for paymaster Mode 1
|
|
29
|
+
*/
|
|
30
|
+
export declare class TacAccountAPI extends BaseAccountAPI {
|
|
31
|
+
publicKey: string;
|
|
32
|
+
signer?: Ed25519Signer;
|
|
33
|
+
tonConnectSigner?: TonConnectSigner;
|
|
34
|
+
factoryAddress: string;
|
|
35
|
+
private accountContract?;
|
|
36
|
+
private factoryContract?;
|
|
37
|
+
constructor(params: TacAccountApiParams);
|
|
38
|
+
private _getAccountContract;
|
|
39
|
+
private _getFactory;
|
|
40
|
+
/** Derive the deterministic account address directly from the factory's view. */
|
|
41
|
+
getCounterFactualAddress(): Promise<string>;
|
|
42
|
+
/** initCode for an undeployed account: factory + `getOrCreateAccount(publicKey)` calldata. */
|
|
43
|
+
getFactoryData(): Promise<FactoryParams | null>;
|
|
44
|
+
/** Sequential nonce from the deployed account, or 0 if still phantom. */
|
|
45
|
+
getNonce(): Promise<bigint>;
|
|
46
|
+
/** Encode a single call as `TacBaseAccount.execute(target, value, data)` calldata. */
|
|
47
|
+
encodeExecute(target: string, value: BigNumberish, data: string): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Sign userOpHash with the configured signer (64-byte raw, or TonConnect with
|
|
50
|
+
* `permitHash = 0`). For paymaster Mode 1 use {@link buildSignedUserOpWithPermit}.
|
|
51
|
+
*/
|
|
52
|
+
signUserOpHash(userOpHash: string): Promise<string>;
|
|
53
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TacAccountAPI = void 0;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const abi_1 = require("./abi");
|
|
6
|
+
const BaseAccountAPI_1 = require("./BaseAccountAPI");
|
|
7
|
+
const Ed25519_1 = require("./Ed25519");
|
|
8
|
+
const ZERO_HASH = '0x' + '00'.repeat(32);
|
|
9
|
+
/**
|
|
10
|
+
* BaseAccountAPI implementation for TAC's Ed25519 + beacon-proxy accounts.
|
|
11
|
+
*
|
|
12
|
+
* - account address is derived from the Ed25519 public key only
|
|
13
|
+
* (`salt = keccak256(publicKey)` inside the factory)
|
|
14
|
+
* - factoryData is `TacAccountFactory.getOrCreateAccount(publicKey)`
|
|
15
|
+
* - signature is Ed25519 in the 64-byte raw format (this class), or the 96-byte /
|
|
16
|
+
* TonConnect formats via {@link buildSignedUserOpWithPermit} for paymaster Mode 1
|
|
17
|
+
*/
|
|
18
|
+
class TacAccountAPI extends BaseAccountAPI_1.BaseAccountAPI {
|
|
19
|
+
constructor(params) {
|
|
20
|
+
super(params);
|
|
21
|
+
if ((params.signer == null) === (params.tonConnectSigner == null)) {
|
|
22
|
+
throw new Error('TacAccountAPI requires exactly one of `signer` or `tonConnectSigner`');
|
|
23
|
+
}
|
|
24
|
+
this.publicKey = params.publicKey;
|
|
25
|
+
this.signer = params.signer;
|
|
26
|
+
this.tonConnectSigner = params.tonConnectSigner;
|
|
27
|
+
this.factoryAddress = params.factoryAddress;
|
|
28
|
+
}
|
|
29
|
+
async _getAccountContract() {
|
|
30
|
+
if (this.accountContract == null) {
|
|
31
|
+
const addr = await this.getAccountAddress();
|
|
32
|
+
this.accountContract = new ethers_1.Contract(addr, abi_1.TacAccountABI, this.provider);
|
|
33
|
+
}
|
|
34
|
+
return this.accountContract;
|
|
35
|
+
}
|
|
36
|
+
_getFactory() {
|
|
37
|
+
if (this.factoryContract == null) {
|
|
38
|
+
this.factoryContract = new ethers_1.Contract(this.factoryAddress, abi_1.TacAccountFactoryABI, this.provider);
|
|
39
|
+
}
|
|
40
|
+
return this.factoryContract;
|
|
41
|
+
}
|
|
42
|
+
/** Derive the deterministic account address directly from the factory's view. */
|
|
43
|
+
async getCounterFactualAddress() {
|
|
44
|
+
return await this._getFactory().getAccountAddress.staticCall(this.publicKey);
|
|
45
|
+
}
|
|
46
|
+
/** initCode for an undeployed account: factory + `getOrCreateAccount(publicKey)` calldata. */
|
|
47
|
+
async getFactoryData() {
|
|
48
|
+
const factory = this._getFactory();
|
|
49
|
+
return {
|
|
50
|
+
factory: this.factoryAddress,
|
|
51
|
+
factoryData: factory.interface.encodeFunctionData('getOrCreateAccount', [this.publicKey]),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Sequential nonce from the deployed account, or 0 if still phantom. */
|
|
55
|
+
async getNonce() {
|
|
56
|
+
if (await this.checkAccountPhantom()) {
|
|
57
|
+
return 0n;
|
|
58
|
+
}
|
|
59
|
+
const accountContract = await this._getAccountContract();
|
|
60
|
+
return await accountContract.getFunction('getNonce()').staticCall();
|
|
61
|
+
}
|
|
62
|
+
/** Encode a single call as `TacBaseAccount.execute(target, value, data)` calldata. */
|
|
63
|
+
async encodeExecute(target, value, data) {
|
|
64
|
+
const accountContract = await this._getAccountContract();
|
|
65
|
+
return accountContract.interface.encodeFunctionData('execute', [target, value, data]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sign userOpHash with the configured signer (64-byte raw, or TonConnect with
|
|
69
|
+
* `permitHash = 0`). For paymaster Mode 1 use {@link buildSignedUserOpWithPermit}.
|
|
70
|
+
*/
|
|
71
|
+
async signUserOpHash(userOpHash) {
|
|
72
|
+
if (this.signer != null) {
|
|
73
|
+
const sig = await this.signer(userOpHash);
|
|
74
|
+
return (0, Ed25519_1.packRawEd25519Signature)(sig);
|
|
75
|
+
}
|
|
76
|
+
if (this.tonConnectSigner != null) {
|
|
77
|
+
const binding = (0, Ed25519_1.buildPermitBinding)(userOpHash, ZERO_HASH);
|
|
78
|
+
const parts = await this.tonConnectSigner(binding);
|
|
79
|
+
return (0, Ed25519_1.packTonConnectUserOpSignature)(parts, ZERO_HASH);
|
|
80
|
+
}
|
|
81
|
+
throw new Error('TacAccountAPI: no signer configured');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.TacAccountAPI = TacAccountAPI;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { AbstractProvider, BigNumberish } from 'ethers';
|
|
2
|
+
import { Network } from '../structs/Struct';
|
|
3
|
+
import { HttpRpcClient } from './HttpRpcClient';
|
|
4
|
+
import { AaAddresses } from './networks';
|
|
5
|
+
import { TacAccountAPI } from './TacAccountAPI';
|
|
6
|
+
/** A single call to execute through the smart account. */
|
|
7
|
+
export interface SendTx {
|
|
8
|
+
target: string;
|
|
9
|
+
data: string;
|
|
10
|
+
value?: BigNumberish;
|
|
11
|
+
/** Defaults to 1_000_000 (the SDK under-estimates the deploying op). */
|
|
12
|
+
gasLimit?: BigNumberish;
|
|
13
|
+
}
|
|
14
|
+
/** Extra options for the permit (Mode 1) flow — all optional. */
|
|
15
|
+
export interface PermitOptions {
|
|
16
|
+
/** Token to pay gas in. Defaults to the paymaster's configured token. */
|
|
17
|
+
feeToken?: string;
|
|
18
|
+
/** Max token the paymaster may pull. Defaults to 1000 units of the fee token. */
|
|
19
|
+
maxFee?: BigNumberish;
|
|
20
|
+
/** Permit deadline (unix seconds). Defaults to no expiry. */
|
|
21
|
+
deadline?: BigNumberish;
|
|
22
|
+
paymasterVerificationGasLimit?: BigNumberish;
|
|
23
|
+
paymasterPostOpGasLimit?: BigNumberish;
|
|
24
|
+
}
|
|
25
|
+
/** The bundler's UserOperation receipt (subset). */
|
|
26
|
+
export interface UserOpReceipt {
|
|
27
|
+
userOpHash: string;
|
|
28
|
+
success: boolean;
|
|
29
|
+
receipt: {
|
|
30
|
+
transactionHash: string;
|
|
31
|
+
blockNumber?: string;
|
|
32
|
+
};
|
|
33
|
+
actualGasCost?: string;
|
|
34
|
+
actualGasUsed?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface UserOpSendResult {
|
|
37
|
+
userOpHash: string;
|
|
38
|
+
receipt: UserOpReceipt;
|
|
39
|
+
}
|
|
40
|
+
export interface TacAccountSdkParams {
|
|
41
|
+
network: Network;
|
|
42
|
+
/** TON mnemonic — the AA account identity. */
|
|
43
|
+
mnemonic: string;
|
|
44
|
+
/** Bundler RPC URL. Required to send (no public default is shipped). */
|
|
45
|
+
bundlerUrl?: string;
|
|
46
|
+
/** Override the TAC EVM provider (default: getDefaultProvider(network's TAC RPC)). */
|
|
47
|
+
provider?: AbstractProvider;
|
|
48
|
+
/** Override any AA contract address. */
|
|
49
|
+
addresses?: Partial<AaAddresses>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* High-level, network-defaulted entry point for the TAC AA bundler — mirrors
|
|
53
|
+
* `TacSdk.create({ network })`. Resolves provider + contract addresses from built-in
|
|
54
|
+
* per-network defaults and derives the signer from a mnemonic; the paymaster/permit data
|
|
55
|
+
* is built internally by the send methods.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* const aa = await TacAccountSdk.create({ network: Network.TESTNET, mnemonic, bundlerUrl });
|
|
59
|
+
* const { userOpHash, receipt } = await aa.sendUserOp({ target, value, data });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare class TacAccountSdk {
|
|
63
|
+
readonly network: Network;
|
|
64
|
+
readonly provider: AbstractProvider;
|
|
65
|
+
readonly addresses: AaAddresses;
|
|
66
|
+
readonly chainId: number;
|
|
67
|
+
readonly bundlerUrl: string | undefined;
|
|
68
|
+
readonly account: TacAccountAPI;
|
|
69
|
+
private readonly _signer;
|
|
70
|
+
private readonly _publicKey;
|
|
71
|
+
private _bundler?;
|
|
72
|
+
private _address?;
|
|
73
|
+
private _tokenInfo?;
|
|
74
|
+
private _permitCounter;
|
|
75
|
+
private constructor();
|
|
76
|
+
static create(params: TacAccountSdkParams): Promise<TacAccountSdk>;
|
|
77
|
+
/** The deterministic smart-account address (derived from the TON public key). */
|
|
78
|
+
getAccountAddress(): Promise<string>;
|
|
79
|
+
/** Send a call paying gas natively (account must hold TAC). */
|
|
80
|
+
sendUserOp(tx: SendTx): Promise<UserOpSendResult>;
|
|
81
|
+
/** Send a call paying gas in an ERC-20 via the paymaster (Mode 1 — Permit2). */
|
|
82
|
+
sendUserOpWithPermit(tx: SendTx & PermitOptions): Promise<UserOpSendResult>;
|
|
83
|
+
/** Send a call paying gas from the account's pre-credited internal balance (Mode 2). */
|
|
84
|
+
sendUserOpViaInternalBalance(tx: SendTx): Promise<UserOpSendResult>;
|
|
85
|
+
/** Send a call where the paymaster pulls the fee token via a pre-set allowance (Mode 0). */
|
|
86
|
+
sendUserOpViaAllowance(tx: SendTx): Promise<UserOpSendResult>;
|
|
87
|
+
/** Poll the bundler for a UserOperation receipt. */
|
|
88
|
+
waitForReceipt(userOpHash: string, opts?: {
|
|
89
|
+
timeoutMs?: number;
|
|
90
|
+
intervalMs?: number;
|
|
91
|
+
}): Promise<UserOpReceipt>;
|
|
92
|
+
/** The bundler client (throws if no bundler URL was configured). */
|
|
93
|
+
bundler(): HttpRpcClient;
|
|
94
|
+
private _bundlerClient;
|
|
95
|
+
private _txDetails;
|
|
96
|
+
private _sendViaMode;
|
|
97
|
+
private _submit;
|
|
98
|
+
private _tokenInfoResolved;
|
|
99
|
+
/** Unique permit nonce (Permit2 replay protection): timestamp-ms high bits + a counter. */
|
|
100
|
+
private _newPermitNonce;
|
|
101
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TacAccountSdk = void 0;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const Artifacts_1 = require("../sdk/Artifacts");
|
|
6
|
+
const HttpRpcClient_1 = require("./HttpRpcClient");
|
|
7
|
+
const networks_1 = require("./networks");
|
|
8
|
+
const PermitFlow_1 = require("./PermitFlow");
|
|
9
|
+
const signer_1 = require("./signer");
|
|
10
|
+
const TacAccountAPI_1 = require("./TacAccountAPI");
|
|
11
|
+
const TacERC20PaymasterAPI_1 = require("./TacERC20PaymasterAPI");
|
|
12
|
+
/**
|
|
13
|
+
* High-level, network-defaulted entry point for the TAC AA bundler — mirrors
|
|
14
|
+
* `TacSdk.create({ network })`. Resolves provider + contract addresses from built-in
|
|
15
|
+
* per-network defaults and derives the signer from a mnemonic; the paymaster/permit data
|
|
16
|
+
* is built internally by the send methods.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const aa = await TacAccountSdk.create({ network: Network.TESTNET, mnemonic, bundlerUrl });
|
|
20
|
+
* const { userOpHash, receipt } = await aa.sendUserOp({ target, value, data });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
class TacAccountSdk {
|
|
24
|
+
constructor(network, provider, addresses, chainId, bundlerUrl, publicKey, signer) {
|
|
25
|
+
this.network = network;
|
|
26
|
+
this.provider = provider;
|
|
27
|
+
this.addresses = addresses;
|
|
28
|
+
this.chainId = chainId;
|
|
29
|
+
this.bundlerUrl = bundlerUrl;
|
|
30
|
+
this._permitCounter = 0;
|
|
31
|
+
this._publicKey = publicKey;
|
|
32
|
+
this._signer = signer;
|
|
33
|
+
this.account = new TacAccountAPI_1.TacAccountAPI({
|
|
34
|
+
provider,
|
|
35
|
+
entryPointAddress: addresses.entryPoint,
|
|
36
|
+
factoryAddress: addresses.accountFactory,
|
|
37
|
+
publicKey,
|
|
38
|
+
signer,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
static async create(params) {
|
|
42
|
+
const cfg = networks_1.AA_NETWORKS[params.network];
|
|
43
|
+
if (cfg == null) {
|
|
44
|
+
throw new Error(`account abstraction is not available on network "${params.network}" yet`);
|
|
45
|
+
}
|
|
46
|
+
let provider = params.provider;
|
|
47
|
+
if (provider == null) {
|
|
48
|
+
const rpc = (0, Artifacts_1.getArtifacts)(params.network).TAC_RPC_ENDPOINT;
|
|
49
|
+
if (rpc == null) {
|
|
50
|
+
throw new Error(`no default TAC RPC for network "${params.network}"; pass a custom provider`);
|
|
51
|
+
}
|
|
52
|
+
provider = (0, ethers_1.getDefaultProvider)(rpc);
|
|
53
|
+
}
|
|
54
|
+
const addresses = {
|
|
55
|
+
entryPoint: params.addresses?.entryPoint ?? cfg.entryPoint,
|
|
56
|
+
accountFactory: params.addresses?.accountFactory ?? cfg.accountFactory,
|
|
57
|
+
paymaster: params.addresses?.paymaster ?? cfg.paymaster,
|
|
58
|
+
permit2: params.addresses?.permit2 ?? cfg.permit2,
|
|
59
|
+
};
|
|
60
|
+
const { publicKey, signer } = await (0, signer_1.aaSignerFromMnemonic)(params.mnemonic);
|
|
61
|
+
return new TacAccountSdk(params.network, provider, addresses, cfg.chainId, params.bundlerUrl ?? cfg.bundlerUrl, publicKey, signer);
|
|
62
|
+
}
|
|
63
|
+
/** The deterministic smart-account address (derived from the TON public key). */
|
|
64
|
+
async getAccountAddress() {
|
|
65
|
+
this._address ?? (this._address = await this.account.getAccountAddress());
|
|
66
|
+
return this._address;
|
|
67
|
+
}
|
|
68
|
+
/** Send a call paying gas natively (account must hold TAC). */
|
|
69
|
+
async sendUserOp(tx) {
|
|
70
|
+
const op = await this.account.createSignedUserOp(this._txDetails(tx));
|
|
71
|
+
return await this._submit(op);
|
|
72
|
+
}
|
|
73
|
+
/** Send a call paying gas in an ERC-20 via the paymaster (Mode 1 — Permit2). */
|
|
74
|
+
async sendUserOpWithPermit(tx) {
|
|
75
|
+
const token = await this._tokenInfoResolved();
|
|
76
|
+
const op = await (0, PermitFlow_1.buildSignedUserOpWithPermit)({
|
|
77
|
+
accountAPI: this.account,
|
|
78
|
+
paymaster: this.addresses.paymaster,
|
|
79
|
+
paymasterVerificationGasLimit: tx.paymasterVerificationGasLimit ?? 500000,
|
|
80
|
+
paymasterPostOpGasLimit: tx.paymasterPostOpGasLimit ?? 150000,
|
|
81
|
+
permitInput: {
|
|
82
|
+
permitted: [{ token: tx.feeToken ?? token.address, amount: tx.maxFee ?? (0, ethers_1.parseUnits)('1000', token.decimals) }],
|
|
83
|
+
nonce: this._newPermitNonce(),
|
|
84
|
+
deadline: tx.deadline ?? ethers_1.MaxUint256,
|
|
85
|
+
chainId: this.chainId,
|
|
86
|
+
verifyingContract: this.addresses.permit2,
|
|
87
|
+
},
|
|
88
|
+
ed25519Signer: this._signer,
|
|
89
|
+
txDetails: this._txDetails(tx),
|
|
90
|
+
});
|
|
91
|
+
return await this._submit(op);
|
|
92
|
+
}
|
|
93
|
+
/** Send a call paying gas from the account's pre-credited internal balance (Mode 2). */
|
|
94
|
+
async sendUserOpViaInternalBalance(tx) {
|
|
95
|
+
return await this._sendViaMode(tx, TacERC20PaymasterAPI_1.TacPaymasterMode.INTERNAL_BALANCE);
|
|
96
|
+
}
|
|
97
|
+
/** Send a call where the paymaster pulls the fee token via a pre-set allowance (Mode 0). */
|
|
98
|
+
async sendUserOpViaAllowance(tx) {
|
|
99
|
+
return await this._sendViaMode(tx, TacERC20PaymasterAPI_1.TacPaymasterMode.TRANSFER_FROM_REQUESTOR);
|
|
100
|
+
}
|
|
101
|
+
/** Poll the bundler for a UserOperation receipt. */
|
|
102
|
+
async waitForReceipt(userOpHash, opts) {
|
|
103
|
+
const client = this._bundlerClient();
|
|
104
|
+
const end = Date.now() + (opts?.timeoutMs ?? 120000);
|
|
105
|
+
while (Date.now() < end) {
|
|
106
|
+
const r = await client.getUserOperationReceipt(userOpHash);
|
|
107
|
+
if (r != null) {
|
|
108
|
+
return r;
|
|
109
|
+
}
|
|
110
|
+
await new Promise((res) => setTimeout(res, opts?.intervalMs ?? 3000));
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`userOp ${userOpHash} not mined within timeout`);
|
|
113
|
+
}
|
|
114
|
+
/** The bundler client (throws if no bundler URL was configured). */
|
|
115
|
+
bundler() {
|
|
116
|
+
return this._bundlerClient();
|
|
117
|
+
}
|
|
118
|
+
// ── internals ──────────────────────────────────────────────────────────────
|
|
119
|
+
_bundlerClient() {
|
|
120
|
+
if (this.bundlerUrl == null || this.bundlerUrl === '') {
|
|
121
|
+
throw new Error('no bundler URL configured — pass `bundlerUrl` to TacAccountSdk.create({ ... })');
|
|
122
|
+
}
|
|
123
|
+
this._bundler ?? (this._bundler = new HttpRpcClient_1.HttpRpcClient(this.bundlerUrl, this.addresses.entryPoint, this.chainId));
|
|
124
|
+
return this._bundler;
|
|
125
|
+
}
|
|
126
|
+
_txDetails(tx) {
|
|
127
|
+
return { target: tx.target, value: tx.value ?? 0, data: tx.data, gasLimit: tx.gasLimit ?? 1000000 };
|
|
128
|
+
}
|
|
129
|
+
async _sendViaMode(tx, mode) {
|
|
130
|
+
const paymasterAPI = new TacERC20PaymasterAPI_1.TacERC20PaymasterAPI({ paymaster: this.addresses.paymaster, mode });
|
|
131
|
+
const account = new TacAccountAPI_1.TacAccountAPI({
|
|
132
|
+
provider: this.provider,
|
|
133
|
+
entryPointAddress: this.addresses.entryPoint,
|
|
134
|
+
factoryAddress: this.addresses.accountFactory,
|
|
135
|
+
publicKey: this._publicKey,
|
|
136
|
+
signer: this._signer,
|
|
137
|
+
accountAddress: await this.getAccountAddress(),
|
|
138
|
+
paymasterAPI,
|
|
139
|
+
});
|
|
140
|
+
const op = await account.createSignedUserOp(this._txDetails(tx));
|
|
141
|
+
return await this._submit(op);
|
|
142
|
+
}
|
|
143
|
+
async _submit(op) {
|
|
144
|
+
const userOpHash = await this._bundlerClient().sendUserOpToBundler(op);
|
|
145
|
+
const receipt = await this.waitForReceipt(userOpHash);
|
|
146
|
+
return { userOpHash, receipt };
|
|
147
|
+
}
|
|
148
|
+
async _tokenInfoResolved() {
|
|
149
|
+
if (this._tokenInfo == null) {
|
|
150
|
+
const pm = new ethers_1.Contract(this.addresses.paymaster, ['function token() view returns (address)'], this.provider);
|
|
151
|
+
const address = await pm.token();
|
|
152
|
+
const erc20 = new ethers_1.Contract(address, ['function decimals() view returns (uint8)'], this.provider);
|
|
153
|
+
const decimals = Number(await erc20.decimals());
|
|
154
|
+
this._tokenInfo = { address, decimals };
|
|
155
|
+
}
|
|
156
|
+
return this._tokenInfo;
|
|
157
|
+
}
|
|
158
|
+
/** Unique permit nonce (Permit2 replay protection): timestamp-ms high bits + a counter. */
|
|
159
|
+
_newPermitNonce() {
|
|
160
|
+
return (BigInt(Date.now()) << 16n) | BigInt(this._permitCounter++ & 0xffff);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.TacAccountSdk = TacAccountSdk;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { BigNumberish, BytesLike } from 'ethers';
|
|
2
|
+
import { PaymasterAPI, PaymasterParams } from './PaymasterAPI';
|
|
3
|
+
/**
|
|
4
|
+
* Mode discriminator consumed by `TacERC20Paymaster._parsePaymasterAndData`. The mode byte
|
|
5
|
+
* sits at index 52 of the full `paymasterAndData` (after `paymaster(20) ‖ pmVerifGas(16) ‖
|
|
6
|
+
* pmPostOpGas(16)`); everything after it is mode-specific.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum TacPaymasterMode {
|
|
9
|
+
/**
|
|
10
|
+
* Paymaster pulls the token from the account via `transferFrom` during validation.
|
|
11
|
+
* The account MUST have pre-approved the paymaster on the token. `paymasterData = 0x00`.
|
|
12
|
+
*/
|
|
13
|
+
TRANSFER_FROM_REQUESTOR = 0,
|
|
14
|
+
/**
|
|
15
|
+
* Paymaster receives a Permit2 `PermitBatchTransferFrom` + signature inside
|
|
16
|
+
* `paymasterData`. Requires the two-round double-sign — use
|
|
17
|
+
* {@link buildSignedUserOpWithPermit}, not this API directly.
|
|
18
|
+
* `paymasterData = 0x01 ‖ abi.encode(PermitBatchTransferFrom, signatureBlob)`.
|
|
19
|
+
*/
|
|
20
|
+
TRANSFER_VIA_PERMIT = 1,
|
|
21
|
+
/**
|
|
22
|
+
* Paymaster debits the account's pre-funded `internalBalance` (credited off-band by
|
|
23
|
+
* the paymaster owner). No approval, no token transfer. `paymasterData = 0x02`.
|
|
24
|
+
*/
|
|
25
|
+
INTERNAL_BALANCE = 2
|
|
26
|
+
}
|
|
27
|
+
export interface TacERC20PaymasterApiParams {
|
|
28
|
+
paymaster: string;
|
|
29
|
+
mode: TacPaymasterMode;
|
|
30
|
+
paymasterVerificationGasLimit?: BigNumberish;
|
|
31
|
+
paymasterPostOpGasLimit?: BigNumberish;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* PaymasterAPI for TAC's `TacERC20Paymaster`. One instance per mode.
|
|
35
|
+
* Modes 0 (TRANSFER_FROM_REQUESTOR) and 2 (INTERNAL_BALANCE) compose directly into a
|
|
36
|
+
* `TacAccountAPI` via its `paymasterAPI`; Mode 1 needs {@link buildSignedUserOpWithPermit}.
|
|
37
|
+
*/
|
|
38
|
+
export declare class TacERC20PaymasterAPI extends PaymasterAPI {
|
|
39
|
+
paymaster: string;
|
|
40
|
+
mode: TacPaymasterMode;
|
|
41
|
+
paymasterVerificationGasLimit: BigNumberish;
|
|
42
|
+
paymasterPostOpGasLimit: BigNumberish;
|
|
43
|
+
constructor(params: TacERC20PaymasterApiParams);
|
|
44
|
+
getTemporaryPaymasterData(): Promise<PaymasterParams | null>;
|
|
45
|
+
getPaymasterData(): Promise<PaymasterParams | null>;
|
|
46
|
+
private _buildPaymasterData;
|
|
47
|
+
}
|
|
48
|
+
/** Pack a single-byte mode discriminator: `0x00`, `0x01`, or `0x02`. */
|
|
49
|
+
export declare function packModeByte(mode: TacPaymasterMode): string;
|
|
50
|
+
/**
|
|
51
|
+
* Assemble the full on-chain `paymasterAndData` field
|
|
52
|
+
* (`paymaster ‖ pmVerifGasLimit ‖ pmPostOpGasLimit ‖ modeByte ‖ extra`).
|
|
53
|
+
*/
|
|
54
|
+
export declare function packPaymasterAndData(params: {
|
|
55
|
+
paymaster: string;
|
|
56
|
+
paymasterVerificationGasLimit: BigNumberish;
|
|
57
|
+
paymasterPostOpGasLimit: BigNumberish;
|
|
58
|
+
paymasterData: BytesLike;
|
|
59
|
+
}): string;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TacERC20PaymasterAPI = exports.TacPaymasterMode = void 0;
|
|
4
|
+
exports.packModeByte = packModeByte;
|
|
5
|
+
exports.packPaymasterAndData = packPaymasterAndData;
|
|
6
|
+
const ethers_1 = require("ethers");
|
|
7
|
+
const PaymasterAPI_1 = require("./PaymasterAPI");
|
|
8
|
+
/**
|
|
9
|
+
* Mode discriminator consumed by `TacERC20Paymaster._parsePaymasterAndData`. The mode byte
|
|
10
|
+
* sits at index 52 of the full `paymasterAndData` (after `paymaster(20) ‖ pmVerifGas(16) ‖
|
|
11
|
+
* pmPostOpGas(16)`); everything after it is mode-specific.
|
|
12
|
+
*/
|
|
13
|
+
var TacPaymasterMode;
|
|
14
|
+
(function (TacPaymasterMode) {
|
|
15
|
+
/**
|
|
16
|
+
* Paymaster pulls the token from the account via `transferFrom` during validation.
|
|
17
|
+
* The account MUST have pre-approved the paymaster on the token. `paymasterData = 0x00`.
|
|
18
|
+
*/
|
|
19
|
+
TacPaymasterMode[TacPaymasterMode["TRANSFER_FROM_REQUESTOR"] = 0] = "TRANSFER_FROM_REQUESTOR";
|
|
20
|
+
/**
|
|
21
|
+
* Paymaster receives a Permit2 `PermitBatchTransferFrom` + signature inside
|
|
22
|
+
* `paymasterData`. Requires the two-round double-sign — use
|
|
23
|
+
* {@link buildSignedUserOpWithPermit}, not this API directly.
|
|
24
|
+
* `paymasterData = 0x01 ‖ abi.encode(PermitBatchTransferFrom, signatureBlob)`.
|
|
25
|
+
*/
|
|
26
|
+
TacPaymasterMode[TacPaymasterMode["TRANSFER_VIA_PERMIT"] = 1] = "TRANSFER_VIA_PERMIT";
|
|
27
|
+
/**
|
|
28
|
+
* Paymaster debits the account's pre-funded `internalBalance` (credited off-band by
|
|
29
|
+
* the paymaster owner). No approval, no token transfer. `paymasterData = 0x02`.
|
|
30
|
+
*/
|
|
31
|
+
TacPaymasterMode[TacPaymasterMode["INTERNAL_BALANCE"] = 2] = "INTERNAL_BALANCE";
|
|
32
|
+
})(TacPaymasterMode || (exports.TacPaymasterMode = TacPaymasterMode = {}));
|
|
33
|
+
const DEFAULT_PM_VERIFICATION_GAS_LIMIT = 100000;
|
|
34
|
+
const DEFAULT_PM_POST_OP_GAS_LIMIT = 100000;
|
|
35
|
+
/**
|
|
36
|
+
* PaymasterAPI for TAC's `TacERC20Paymaster`. One instance per mode.
|
|
37
|
+
* Modes 0 (TRANSFER_FROM_REQUESTOR) and 2 (INTERNAL_BALANCE) compose directly into a
|
|
38
|
+
* `TacAccountAPI` via its `paymasterAPI`; Mode 1 needs {@link buildSignedUserOpWithPermit}.
|
|
39
|
+
*/
|
|
40
|
+
class TacERC20PaymasterAPI extends PaymasterAPI_1.PaymasterAPI {
|
|
41
|
+
constructor(params) {
|
|
42
|
+
super();
|
|
43
|
+
this.paymaster = params.paymaster;
|
|
44
|
+
this.mode = params.mode;
|
|
45
|
+
this.paymasterVerificationGasLimit = params.paymasterVerificationGasLimit ?? DEFAULT_PM_VERIFICATION_GAS_LIMIT;
|
|
46
|
+
this.paymasterPostOpGasLimit = params.paymasterPostOpGasLimit ?? DEFAULT_PM_POST_OP_GAS_LIMIT;
|
|
47
|
+
}
|
|
48
|
+
async getTemporaryPaymasterData() {
|
|
49
|
+
return await this.getPaymasterData();
|
|
50
|
+
}
|
|
51
|
+
async getPaymasterData() {
|
|
52
|
+
return {
|
|
53
|
+
paymaster: this.paymaster,
|
|
54
|
+
paymasterVerificationGasLimit: this.paymasterVerificationGasLimit,
|
|
55
|
+
paymasterPostOpGasLimit: this.paymasterPostOpGasLimit,
|
|
56
|
+
paymasterData: this._buildPaymasterData(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
_buildPaymasterData() {
|
|
60
|
+
switch (this.mode) {
|
|
61
|
+
case TacPaymasterMode.TRANSFER_FROM_REQUESTOR:
|
|
62
|
+
case TacPaymasterMode.INTERNAL_BALANCE:
|
|
63
|
+
return packModeByte(this.mode);
|
|
64
|
+
case TacPaymasterMode.TRANSFER_VIA_PERMIT:
|
|
65
|
+
throw new Error('TacPaymasterMode.TRANSFER_VIA_PERMIT requires the double-signing flow. ' +
|
|
66
|
+
'Use buildSignedUserOpWithPermit(...) instead of composing this PaymasterAPI into a TacAccountAPI.');
|
|
67
|
+
default:
|
|
68
|
+
throw new Error(`unknown TacPaymasterMode: ${this.mode}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.TacERC20PaymasterAPI = TacERC20PaymasterAPI;
|
|
73
|
+
/** Pack a single-byte mode discriminator: `0x00`, `0x01`, or `0x02`. */
|
|
74
|
+
function packModeByte(mode) {
|
|
75
|
+
return (0, ethers_1.zeroPadValue)((0, ethers_1.toBeHex)(mode), 1);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Assemble the full on-chain `paymasterAndData` field
|
|
79
|
+
* (`paymaster ‖ pmVerifGasLimit ‖ pmPostOpGasLimit ‖ modeByte ‖ extra`).
|
|
80
|
+
*/
|
|
81
|
+
function packPaymasterAndData(params) {
|
|
82
|
+
return (0, ethers_1.concat)([
|
|
83
|
+
params.paymaster,
|
|
84
|
+
(0, ethers_1.zeroPadValue)((0, ethers_1.toBeHex)(params.paymasterVerificationGasLimit), 16),
|
|
85
|
+
(0, ethers_1.zeroPadValue)((0, ethers_1.toBeHex)(params.paymasterPostOpGasLimit), 16),
|
|
86
|
+
params.paymasterData,
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BigNumberish } from 'ethers';
|
|
2
|
+
export interface TransactionDetailsForUserOp {
|
|
3
|
+
target: string;
|
|
4
|
+
data: string;
|
|
5
|
+
value?: BigNumberish;
|
|
6
|
+
gasLimit?: BigNumberish;
|
|
7
|
+
maxFeePerGas?: BigNumberish;
|
|
8
|
+
maxPriorityFeePerGas?: BigNumberish;
|
|
9
|
+
nonce?: BigNumberish;
|
|
10
|
+
}
|