@coinbase/agentkit 0.9.1 → 0.10.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/README.md +106 -54
- package/dist/action-providers/cdp/cdpApiActionProvider.js +2 -0
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.d.ts +43 -0
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +151 -0
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.d.ts +1 -0
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +242 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.d.ts +42 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +132 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.d.ts +1 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +199 -0
- package/dist/action-providers/cdp/index.d.ts +3 -0
- package/dist/action-providers/cdp/index.js +3 -0
- package/dist/action-providers/cdp/schemas.d.ts +29 -0
- package/dist/action-providers/cdp/schemas.js +32 -1
- package/dist/action-providers/cdp/spendPermissionUtils.d.ts +24 -0
- package/dist/action-providers/cdp/spendPermissionUtils.js +66 -0
- package/dist/action-providers/index.d.ts +1 -0
- package/dist/action-providers/index.js +1 -0
- package/dist/action-providers/zerion/constants.d.ts +1 -0
- package/dist/action-providers/zerion/constants.js +4 -0
- package/dist/action-providers/zerion/index.d.ts +2 -0
- package/dist/action-providers/zerion/index.js +18 -0
- package/dist/action-providers/zerion/schemas.d.ts +11 -0
- package/dist/action-providers/zerion/schemas.js +15 -0
- package/dist/action-providers/zerion/types.d.ts +125 -0
- package/dist/action-providers/zerion/types.js +16 -0
- package/dist/action-providers/zerion/utils.d.ts +3 -0
- package/dist/action-providers/zerion/utils.js +45 -0
- package/dist/action-providers/zerion/zerionActionProvider.d.ts +57 -0
- package/dist/action-providers/zerion/zerionActionProvider.js +159 -0
- package/dist/action-providers/zerion/zerionActionProvider.test.d.ts +1 -0
- package/dist/action-providers/zerion/zerionActionProvider.test.js +213 -0
- package/dist/wallet-providers/cdpShared.d.ts +4 -0
- package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +8 -1
- package/dist/wallet-providers/cdpSmartWalletProvider.js +23 -11
- package/package.json +2 -2
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CdpSmartWalletProvider } from "../../wallet-providers/cdpSmartWalletProvider";
|
|
3
|
+
import { ActionProvider } from "../actionProvider";
|
|
4
|
+
import { UseSpendPermissionSchema, ListSpendPermissionsSchema } from "./schemas";
|
|
5
|
+
import type { Network } from "../../network";
|
|
6
|
+
/**
|
|
7
|
+
* CdpSmartWalletActionProvider is an action provider for CDP Smart Wallet specific actions.
|
|
8
|
+
*
|
|
9
|
+
* This provider is scoped specifically to CdpSmartWalletProvider and provides actions
|
|
10
|
+
* that are optimized for smart wallet functionality.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CdpSmartWalletActionProvider extends ActionProvider<CdpSmartWalletProvider> {
|
|
13
|
+
#private;
|
|
14
|
+
/**
|
|
15
|
+
* Constructor for the CdpSmartWalletActionProvider class.
|
|
16
|
+
*/
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Lists spend permissions for a smart account.
|
|
20
|
+
*
|
|
21
|
+
* @param walletProvider - The smart wallet provider to use for listing permissions.
|
|
22
|
+
* @param args - The input arguments for listing spend permissions.
|
|
23
|
+
* @returns A list of spend permissions available to the current wallet.
|
|
24
|
+
*/
|
|
25
|
+
listSpendPermissions(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof ListSpendPermissionsSchema>): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Uses a spend permission to transfer tokens from a smart account to the current smart wallet.
|
|
28
|
+
*
|
|
29
|
+
* @param walletProvider - The smart wallet provider to use for the spend operation.
|
|
30
|
+
* @param args - The input arguments for using the spend permission.
|
|
31
|
+
* @returns A confirmation message with transaction details.
|
|
32
|
+
*/
|
|
33
|
+
useSpendPermission(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof UseSpendPermissionSchema>): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Checks if the smart wallet action provider supports the given network.
|
|
36
|
+
*
|
|
37
|
+
* @param _ - The network to check.
|
|
38
|
+
* @returns True if the smart wallet action provider supports the network, false otherwise.
|
|
39
|
+
*/
|
|
40
|
+
supportsNetwork: (_: Network) => boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare const cdpSmartWalletActionProvider: () => CdpSmartWalletActionProvider;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
12
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
13
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
|
+
};
|
|
16
|
+
var _CdpSmartWalletActionProvider_instances, _CdpSmartWalletActionProvider_getCdpSdkNetwork;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.cdpSmartWalletActionProvider = exports.CdpSmartWalletActionProvider = void 0;
|
|
19
|
+
const zod_1 = require("zod");
|
|
20
|
+
const cdpSmartWalletProvider_1 = require("../../wallet-providers/cdpSmartWalletProvider");
|
|
21
|
+
const actionDecorator_1 = require("../actionDecorator");
|
|
22
|
+
const actionProvider_1 = require("../actionProvider");
|
|
23
|
+
const schemas_1 = require("./schemas");
|
|
24
|
+
const spendPermissionUtils_1 = require("./spendPermissionUtils");
|
|
25
|
+
/**
|
|
26
|
+
* CdpSmartWalletActionProvider is an action provider for CDP Smart Wallet specific actions.
|
|
27
|
+
*
|
|
28
|
+
* This provider is scoped specifically to CdpSmartWalletProvider and provides actions
|
|
29
|
+
* that are optimized for smart wallet functionality.
|
|
30
|
+
*/
|
|
31
|
+
class CdpSmartWalletActionProvider extends actionProvider_1.ActionProvider {
|
|
32
|
+
/**
|
|
33
|
+
* Constructor for the CdpSmartWalletActionProvider class.
|
|
34
|
+
*/
|
|
35
|
+
constructor() {
|
|
36
|
+
super("cdp_smart_wallet", []);
|
|
37
|
+
_CdpSmartWalletActionProvider_instances.add(this);
|
|
38
|
+
/**
|
|
39
|
+
* Checks if the smart wallet action provider supports the given network.
|
|
40
|
+
*
|
|
41
|
+
* @param _ - The network to check.
|
|
42
|
+
* @returns True if the smart wallet action provider supports the network, false otherwise.
|
|
43
|
+
*/
|
|
44
|
+
this.supportsNetwork = (_) => {
|
|
45
|
+
return true;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Lists spend permissions for a smart account.
|
|
50
|
+
*
|
|
51
|
+
* @param walletProvider - The smart wallet provider to use for listing permissions.
|
|
52
|
+
* @param args - The input arguments for listing spend permissions.
|
|
53
|
+
* @returns A list of spend permissions available to the current wallet.
|
|
54
|
+
*/
|
|
55
|
+
async listSpendPermissions(walletProvider, args) {
|
|
56
|
+
const network = walletProvider.getNetwork();
|
|
57
|
+
if (network.protocolFamily === "evm") {
|
|
58
|
+
const spenderAddress = walletProvider.getAddress();
|
|
59
|
+
return await (0, spendPermissionUtils_1.listSpendPermissionsForSpender)(walletProvider.getClient(), args.smartAccountAddress, spenderAddress);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return "Spend permissions are currently only supported on EVM networks.";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Uses a spend permission to transfer tokens from a smart account to the current smart wallet.
|
|
67
|
+
*
|
|
68
|
+
* @param walletProvider - The smart wallet provider to use for the spend operation.
|
|
69
|
+
* @param args - The input arguments for using the spend permission.
|
|
70
|
+
* @returns A confirmation message with transaction details.
|
|
71
|
+
*/
|
|
72
|
+
async useSpendPermission(walletProvider, args) {
|
|
73
|
+
const network = walletProvider.getNetwork();
|
|
74
|
+
const cdpNetwork = __classPrivateFieldGet(this, _CdpSmartWalletActionProvider_instances, "m", _CdpSmartWalletActionProvider_getCdpSdkNetwork).call(this, network.networkId);
|
|
75
|
+
if (network.protocolFamily === "evm") {
|
|
76
|
+
try {
|
|
77
|
+
const permission = await (0, spendPermissionUtils_1.findLatestSpendPermission)(walletProvider.getClient(), args.smartAccountAddress, walletProvider.getAddress());
|
|
78
|
+
const spendResult = await walletProvider.smartAccount.useSpendPermission({
|
|
79
|
+
spendPermission: permission,
|
|
80
|
+
value: BigInt(args.value),
|
|
81
|
+
network: cdpNetwork,
|
|
82
|
+
});
|
|
83
|
+
return `Successfully spent ${args.value} tokens using spend permission. Status: ${spendResult.status}`;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
throw new Error(`Failed to use spend permission: ${error}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
throw new Error("Spend permissions are currently only supported on EVM networks.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.CdpSmartWalletActionProvider = CdpSmartWalletActionProvider;
|
|
95
|
+
_CdpSmartWalletActionProvider_instances = new WeakSet(), _CdpSmartWalletActionProvider_getCdpSdkNetwork = function _CdpSmartWalletActionProvider_getCdpSdkNetwork(networkId) {
|
|
96
|
+
switch (networkId) {
|
|
97
|
+
case "base-sepolia":
|
|
98
|
+
return "base-sepolia";
|
|
99
|
+
case "base-mainnet":
|
|
100
|
+
return "base";
|
|
101
|
+
default:
|
|
102
|
+
throw new Error(`Unsupported network for smart wallets: ${networkId}`);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
__decorate([
|
|
106
|
+
(0, actionDecorator_1.CreateAction)({
|
|
107
|
+
name: "list_spend_permissions",
|
|
108
|
+
description: `This tool lists spend permissions that have been granted to the current smart wallet by another smart account.
|
|
109
|
+
It takes a smart account address and returns spend permissions where the current smart wallet is the spender.
|
|
110
|
+
This is useful to see what spending allowances have been granted before using them.
|
|
111
|
+
This action is specifically designed for smart wallets.`,
|
|
112
|
+
schema: schemas_1.ListSpendPermissionsSchema,
|
|
113
|
+
}),
|
|
114
|
+
__metadata("design:type", Function),
|
|
115
|
+
__metadata("design:paramtypes", [cdpSmartWalletProvider_1.CdpSmartWalletProvider, void 0]),
|
|
116
|
+
__metadata("design:returntype", Promise)
|
|
117
|
+
], CdpSmartWalletActionProvider.prototype, "listSpendPermissions", null);
|
|
118
|
+
__decorate([
|
|
119
|
+
(0, actionDecorator_1.CreateAction)({
|
|
120
|
+
name: "use_spend_permission",
|
|
121
|
+
description: `This tool uses a spend permission to spend tokens on behalf of a smart account that the current smart wallet has permission to spend.
|
|
122
|
+
It automatically finds the latest valid spend permission granted by the smart account to the current smart wallet and uses it to spend the specified amount.
|
|
123
|
+
The smart account must have previously granted a spend permission to the current smart wallet using createSpendPermission.
|
|
124
|
+
This action is specifically designed for smart wallets and uses the smart account directly for optimal performance.`,
|
|
125
|
+
schema: schemas_1.UseSpendPermissionSchema,
|
|
126
|
+
}),
|
|
127
|
+
__metadata("design:type", Function),
|
|
128
|
+
__metadata("design:paramtypes", [cdpSmartWalletProvider_1.CdpSmartWalletProvider, void 0]),
|
|
129
|
+
__metadata("design:returntype", Promise)
|
|
130
|
+
], CdpSmartWalletActionProvider.prototype, "useSpendPermission", null);
|
|
131
|
+
const cdpSmartWalletActionProvider = () => new CdpSmartWalletActionProvider();
|
|
132
|
+
exports.cdpSmartWalletActionProvider = cdpSmartWalletActionProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const cdpSmartWalletActionProvider_1 = require("./cdpSmartWalletActionProvider");
|
|
37
|
+
const schemas_1 = require("./schemas");
|
|
38
|
+
const spendPermissionUtils = __importStar(require("./spendPermissionUtils"));
|
|
39
|
+
// Mock the CDP SDK and utility functions
|
|
40
|
+
jest.mock("@coinbase/cdp-sdk");
|
|
41
|
+
jest.mock("./spendPermissionUtils");
|
|
42
|
+
describe("CDP Smart Wallet Action Provider", () => {
|
|
43
|
+
let actionProvider;
|
|
44
|
+
let mockWalletProvider;
|
|
45
|
+
let mockCdpClient;
|
|
46
|
+
let mockSmartAccount;
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
jest.clearAllMocks();
|
|
49
|
+
mockSmartAccount = {
|
|
50
|
+
useSpendPermission: jest.fn(),
|
|
51
|
+
address: "0x1234567890123456789012345678901234567890",
|
|
52
|
+
};
|
|
53
|
+
mockCdpClient = {
|
|
54
|
+
evm: {
|
|
55
|
+
listSpendPermissions: jest.fn(),
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
mockWalletProvider = {
|
|
59
|
+
getNetwork: jest.fn(),
|
|
60
|
+
getAddress: jest.fn(),
|
|
61
|
+
getClient: jest.fn(),
|
|
62
|
+
smartAccount: mockSmartAccount,
|
|
63
|
+
};
|
|
64
|
+
actionProvider = new cdpSmartWalletActionProvider_1.CdpSmartWalletActionProvider();
|
|
65
|
+
});
|
|
66
|
+
describe("listSpendPermissions", () => {
|
|
67
|
+
const mockArgs = {
|
|
68
|
+
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
|
|
69
|
+
};
|
|
70
|
+
beforeEach(() => {
|
|
71
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
72
|
+
protocolFamily: "evm",
|
|
73
|
+
networkId: "base-sepolia",
|
|
74
|
+
});
|
|
75
|
+
mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
|
|
76
|
+
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
77
|
+
});
|
|
78
|
+
it("should successfully list spend permissions for EVM networks", async () => {
|
|
79
|
+
const expectedResult = "Found 1 spend permission(s):\n1. Token: ETH, Allowance: 1000, Period: 3600 seconds, Start: 123456, End: 234567";
|
|
80
|
+
spendPermissionUtils.listSpendPermissionsForSpender.mockResolvedValue(expectedResult);
|
|
81
|
+
const result = await actionProvider.listSpendPermissions(mockWalletProvider, mockArgs);
|
|
82
|
+
expect(spendPermissionUtils.listSpendPermissionsForSpender).toHaveBeenCalledWith(mockCdpClient, mockArgs.smartAccountAddress, "0x1234567890123456789012345678901234567890");
|
|
83
|
+
expect(result).toBe(expectedResult);
|
|
84
|
+
});
|
|
85
|
+
it("should return error message for non-EVM networks", async () => {
|
|
86
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
87
|
+
protocolFamily: "svm",
|
|
88
|
+
networkId: "solana-devnet",
|
|
89
|
+
});
|
|
90
|
+
const result = await actionProvider.listSpendPermissions(mockWalletProvider, mockArgs);
|
|
91
|
+
expect(result).toBe("Spend permissions are currently only supported on EVM networks.");
|
|
92
|
+
expect(spendPermissionUtils.listSpendPermissionsForSpender).not.toHaveBeenCalled();
|
|
93
|
+
});
|
|
94
|
+
it("should validate input schema", () => {
|
|
95
|
+
const validInput = { smartAccountAddress: "0xabcd1234567890123456789012345678901234567890" };
|
|
96
|
+
const invalidInput = { invalidField: "invalid" };
|
|
97
|
+
expect(() => schemas_1.ListSpendPermissionsSchema.parse(validInput)).not.toThrow();
|
|
98
|
+
expect(() => schemas_1.ListSpendPermissionsSchema.parse(invalidInput)).toThrow();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("useSpendPermission", () => {
|
|
102
|
+
const mockArgs = {
|
|
103
|
+
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
|
|
104
|
+
value: "1000",
|
|
105
|
+
};
|
|
106
|
+
beforeEach(() => {
|
|
107
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
108
|
+
protocolFamily: "evm",
|
|
109
|
+
networkId: "base-sepolia",
|
|
110
|
+
});
|
|
111
|
+
mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
|
|
112
|
+
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
113
|
+
});
|
|
114
|
+
it("should successfully use spend permission for EVM networks", async () => {
|
|
115
|
+
const mockPermission = {
|
|
116
|
+
spender: "0x1234567890123456789012345678901234567890",
|
|
117
|
+
token: "ETH",
|
|
118
|
+
allowance: "1000",
|
|
119
|
+
period: 3600,
|
|
120
|
+
start: 123456,
|
|
121
|
+
end: 234567,
|
|
122
|
+
};
|
|
123
|
+
const mockSpendResult = {
|
|
124
|
+
status: "completed",
|
|
125
|
+
transactionHash: "0xabcd1234",
|
|
126
|
+
};
|
|
127
|
+
spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
|
|
128
|
+
mockSmartAccount.useSpendPermission.mockResolvedValue(mockSpendResult);
|
|
129
|
+
const result = await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
|
|
130
|
+
expect(spendPermissionUtils.findLatestSpendPermission).toHaveBeenCalledWith(mockCdpClient, mockArgs.smartAccountAddress, "0x1234567890123456789012345678901234567890");
|
|
131
|
+
expect(mockSmartAccount.useSpendPermission).toHaveBeenCalledWith({
|
|
132
|
+
spendPermission: mockPermission,
|
|
133
|
+
value: BigInt(1000),
|
|
134
|
+
network: "base-sepolia",
|
|
135
|
+
});
|
|
136
|
+
expect(result).toBe("Successfully spent 1000 tokens using spend permission. Status: completed");
|
|
137
|
+
});
|
|
138
|
+
it("should handle base-mainnet network conversion", async () => {
|
|
139
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
140
|
+
protocolFamily: "evm",
|
|
141
|
+
networkId: "base-mainnet",
|
|
142
|
+
});
|
|
143
|
+
const mockPermission = { spender: "0x1234", token: "ETH" };
|
|
144
|
+
const mockSpendResult = { status: "completed" };
|
|
145
|
+
spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
|
|
146
|
+
mockSmartAccount.useSpendPermission.mockResolvedValue(mockSpendResult);
|
|
147
|
+
await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
|
|
148
|
+
expect(mockSmartAccount.useSpendPermission).toHaveBeenCalledWith({
|
|
149
|
+
spendPermission: mockPermission,
|
|
150
|
+
value: BigInt(1000),
|
|
151
|
+
network: "base",
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
it("should throw error for unsupported networks", async () => {
|
|
155
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
156
|
+
protocolFamily: "evm",
|
|
157
|
+
networkId: "ethereum-mainnet",
|
|
158
|
+
});
|
|
159
|
+
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Unsupported network for smart wallets: ethereum-mainnet");
|
|
160
|
+
});
|
|
161
|
+
it("should return error message for non-EVM networks", async () => {
|
|
162
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
163
|
+
protocolFamily: "svm",
|
|
164
|
+
networkId: "solana-devnet",
|
|
165
|
+
});
|
|
166
|
+
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Unsupported network for smart wallets: solana-devnet");
|
|
167
|
+
});
|
|
168
|
+
it("should handle spend permission not found error", async () => {
|
|
169
|
+
spendPermissionUtils.findLatestSpendPermission.mockRejectedValue(new Error("No spend permissions found"));
|
|
170
|
+
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Failed to use spend permission: Error: No spend permissions found");
|
|
171
|
+
});
|
|
172
|
+
it("should handle smart account use permission failure", async () => {
|
|
173
|
+
const mockPermission = { spender: "0x1234", token: "ETH" };
|
|
174
|
+
spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
|
|
175
|
+
mockSmartAccount.useSpendPermission.mockRejectedValue(new Error("Transaction failed"));
|
|
176
|
+
await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Failed to use spend permission: Error: Transaction failed");
|
|
177
|
+
});
|
|
178
|
+
it("should validate input schema", () => {
|
|
179
|
+
const validInput = {
|
|
180
|
+
smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
|
|
181
|
+
value: "1000",
|
|
182
|
+
};
|
|
183
|
+
const invalidInput = {
|
|
184
|
+
wrongField: "0xabcd1234567890123456789012345678901234567890",
|
|
185
|
+
// Missing required fields
|
|
186
|
+
};
|
|
187
|
+
expect(() => schemas_1.UseSpendPermissionSchema.parse(validInput)).not.toThrow();
|
|
188
|
+
expect(() => schemas_1.UseSpendPermissionSchema.parse(invalidInput)).toThrow();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
describe("supportsNetwork", () => {
|
|
192
|
+
it("should return true for any network", () => {
|
|
193
|
+
const evmNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
|
|
194
|
+
const svmNetwork = { protocolFamily: "svm", networkId: "solana-devnet" };
|
|
195
|
+
expect(actionProvider.supportsNetwork(evmNetwork)).toBe(true);
|
|
196
|
+
expect(actionProvider.supportsNetwork(svmNetwork)).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
@@ -16,3 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./schemas"), exports);
|
|
18
18
|
__exportStar(require("./cdpApiActionProvider"), exports);
|
|
19
|
+
__exportStar(require("./cdpSmartWalletActionProvider"), exports);
|
|
20
|
+
__exportStar(require("./cdpEvmWalletActionProvider"), exports);
|
|
21
|
+
__exportStar(require("./spendPermissionUtils"), exports);
|
|
@@ -28,3 +28,32 @@ export declare const SwapSchema: z.ZodObject<{
|
|
|
28
28
|
toAssetId: string;
|
|
29
29
|
network?: string | undefined;
|
|
30
30
|
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Input schema for listing spend permissions action.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ListSpendPermissionsSchema: z.ZodObject<{
|
|
35
|
+
smartAccountAddress: z.ZodString;
|
|
36
|
+
network: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, "strip", z.ZodTypeAny, {
|
|
38
|
+
smartAccountAddress: string;
|
|
39
|
+
network?: string | undefined;
|
|
40
|
+
}, {
|
|
41
|
+
smartAccountAddress: string;
|
|
42
|
+
network?: string | undefined;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Input schema for using a spend permission action.
|
|
46
|
+
*/
|
|
47
|
+
export declare const UseSpendPermissionSchema: z.ZodObject<{
|
|
48
|
+
smartAccountAddress: z.ZodString;
|
|
49
|
+
value: z.ZodString;
|
|
50
|
+
network: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
value: string;
|
|
53
|
+
smartAccountAddress: string;
|
|
54
|
+
network?: string | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
value: string;
|
|
57
|
+
smartAccountAddress: string;
|
|
58
|
+
network?: string | undefined;
|
|
59
|
+
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SwapSchema = exports.RequestFaucetFundsV2Schema = void 0;
|
|
3
|
+
exports.UseSpendPermissionSchema = exports.ListSpendPermissionsSchema = exports.SwapSchema = exports.RequestFaucetFundsV2Schema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
/**
|
|
6
6
|
* Input schema for request faucet funds action.
|
|
@@ -26,3 +26,34 @@ exports.SwapSchema = zod_1.z
|
|
|
26
26
|
})
|
|
27
27
|
.strip()
|
|
28
28
|
.describe("Instructions for swapping tokens");
|
|
29
|
+
/**
|
|
30
|
+
* Input schema for listing spend permissions action.
|
|
31
|
+
*/
|
|
32
|
+
exports.ListSpendPermissionsSchema = zod_1.z
|
|
33
|
+
.object({
|
|
34
|
+
smartAccountAddress: zod_1.z
|
|
35
|
+
.string()
|
|
36
|
+
.describe("The smart account address that has granted spend permissions"),
|
|
37
|
+
network: zod_1.z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("The network to list permissions on (defaults to wallet's network)"),
|
|
41
|
+
})
|
|
42
|
+
.strip()
|
|
43
|
+
.describe("Instructions for listing spend permissions for a smart account");
|
|
44
|
+
/**
|
|
45
|
+
* Input schema for using a spend permission action.
|
|
46
|
+
*/
|
|
47
|
+
exports.UseSpendPermissionSchema = zod_1.z
|
|
48
|
+
.object({
|
|
49
|
+
smartAccountAddress: zod_1.z
|
|
50
|
+
.string()
|
|
51
|
+
.describe("The smart account address that has granted the spend permission"),
|
|
52
|
+
value: zod_1.z.string().describe("The amount to spend (in the token's units)"),
|
|
53
|
+
network: zod_1.z
|
|
54
|
+
.string()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("The network to perform the spend on (defaults to wallet's network)"),
|
|
57
|
+
})
|
|
58
|
+
.strip()
|
|
59
|
+
.describe("Instructions for using a spend permission");
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CdpClient, type SpendPermission } from "@coinbase/cdp-sdk";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
/**
|
|
4
|
+
* Shared utility functions for spend permission operations.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Lists and formats spend permissions for a given smart account and spender.
|
|
8
|
+
*
|
|
9
|
+
* @param cdpClient - The CDP client to use for API calls
|
|
10
|
+
* @param smartAccountAddress - The smart account address to check permissions for
|
|
11
|
+
* @param spenderAddress - The spender address to filter permissions by
|
|
12
|
+
* @returns A formatted string containing the spend permissions or an error message
|
|
13
|
+
*/
|
|
14
|
+
export declare function listSpendPermissionsForSpender(cdpClient: CdpClient, smartAccountAddress: Address, spenderAddress: Address): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Finds and retrieves the latest valid spend permission for a given spender from a smart account.
|
|
17
|
+
*
|
|
18
|
+
* @param cdpClient - The CDP client to use for API calls
|
|
19
|
+
* @param smartAccountAddress - The smart account address to check permissions for
|
|
20
|
+
* @param spenderAddress - The spender address to find permissions for
|
|
21
|
+
* @returns The latest spend permission or throws an error if none found
|
|
22
|
+
* @throws Error if no permissions found or permission is invalid
|
|
23
|
+
*/
|
|
24
|
+
export declare function findLatestSpendPermission(cdpClient: CdpClient, smartAccountAddress: Address, spenderAddress: Address): Promise<SpendPermission>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listSpendPermissionsForSpender = listSpendPermissionsForSpender;
|
|
4
|
+
exports.findLatestSpendPermission = findLatestSpendPermission;
|
|
5
|
+
/**
|
|
6
|
+
* Shared utility functions for spend permission operations.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Lists and formats spend permissions for a given smart account and spender.
|
|
10
|
+
*
|
|
11
|
+
* @param cdpClient - The CDP client to use for API calls
|
|
12
|
+
* @param smartAccountAddress - The smart account address to check permissions for
|
|
13
|
+
* @param spenderAddress - The spender address to filter permissions by
|
|
14
|
+
* @returns A formatted string containing the spend permissions or an error message
|
|
15
|
+
*/
|
|
16
|
+
async function listSpendPermissionsForSpender(cdpClient, smartAccountAddress, spenderAddress) {
|
|
17
|
+
try {
|
|
18
|
+
// List all spend permissions for the smart account
|
|
19
|
+
const allPermissions = await cdpClient.evm.listSpendPermissions({
|
|
20
|
+
address: smartAccountAddress,
|
|
21
|
+
});
|
|
22
|
+
// Filter permissions where current wallet is the spender
|
|
23
|
+
const relevantPermissions = allPermissions.spendPermissions.filter(p => p.permission?.spender.toLowerCase() === spenderAddress.toLowerCase());
|
|
24
|
+
if (relevantPermissions.length === 0) {
|
|
25
|
+
return `No spend permissions found for spender ${spenderAddress} on smart account ${smartAccountAddress}`;
|
|
26
|
+
}
|
|
27
|
+
// Format the permissions for display
|
|
28
|
+
const formattedPermissions = relevantPermissions
|
|
29
|
+
.map((p, index) => {
|
|
30
|
+
const perm = p.permission;
|
|
31
|
+
if (!perm)
|
|
32
|
+
return `${index + 1}. Invalid permission`;
|
|
33
|
+
return `${index + 1}. Token: ${perm.token}, Allowance: ${perm.allowance}, Period: ${perm.period} seconds, Start: ${perm.start}, End: ${perm.end}`;
|
|
34
|
+
})
|
|
35
|
+
.join("\n");
|
|
36
|
+
return `Found ${relevantPermissions.length} spend permission(s):\n${formattedPermissions}`;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return `Failed to list spend permissions: ${error}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Finds and retrieves the latest valid spend permission for a given spender from a smart account.
|
|
44
|
+
*
|
|
45
|
+
* @param cdpClient - The CDP client to use for API calls
|
|
46
|
+
* @param smartAccountAddress - The smart account address to check permissions for
|
|
47
|
+
* @param spenderAddress - The spender address to find permissions for
|
|
48
|
+
* @returns The latest spend permission or throws an error if none found
|
|
49
|
+
* @throws Error if no permissions found or permission is invalid
|
|
50
|
+
*/
|
|
51
|
+
async function findLatestSpendPermission(cdpClient, smartAccountAddress, spenderAddress) {
|
|
52
|
+
const allPermissions = await cdpClient.evm.listSpendPermissions({
|
|
53
|
+
address: smartAccountAddress,
|
|
54
|
+
});
|
|
55
|
+
// Filter permissions where current wallet is the spender
|
|
56
|
+
const relevantPermissions = allPermissions.spendPermissions.filter(p => p.permission?.spender.toLowerCase() === spenderAddress.toLowerCase());
|
|
57
|
+
if (relevantPermissions.length === 0) {
|
|
58
|
+
throw new Error(`No spend permissions found for spender ${spenderAddress} on smart account ${smartAccountAddress}`);
|
|
59
|
+
}
|
|
60
|
+
// Use the latest permission (last in the array)
|
|
61
|
+
const latestPermissionWrapper = relevantPermissions.at(-1);
|
|
62
|
+
if (!latestPermissionWrapper?.permission) {
|
|
63
|
+
throw new Error("Invalid spend permission found");
|
|
64
|
+
}
|
|
65
|
+
return latestPermissionWrapper.permission;
|
|
66
|
+
}
|
|
@@ -44,5 +44,6 @@ __exportStar(require("./flaunch"), exports);
|
|
|
44
44
|
__exportStar(require("./onramp"), exports);
|
|
45
45
|
__exportStar(require("./vaultsfyi"), exports);
|
|
46
46
|
__exportStar(require("./x402"), exports);
|
|
47
|
+
__exportStar(require("./zerion"), exports);
|
|
47
48
|
__exportStar(require("./zerodev"), exports);
|
|
48
49
|
__exportStar(require("./zora"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ZERION_V1_BASE_URL = "https://api.zerion.io/v1";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./zerionActionProvider"), exports);
|
|
18
|
+
__exportStar(require("./schemas"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Input schema for getting wallet portfolio.
|
|
4
|
+
*/
|
|
5
|
+
export declare const GetWalletPortfolioSchema: z.ZodObject<{
|
|
6
|
+
walletAddress: z.ZodString;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
walletAddress: string;
|
|
9
|
+
}, {
|
|
10
|
+
walletAddress: string;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetWalletPortfolioSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
/**
|
|
6
|
+
* Input schema for getting wallet portfolio.
|
|
7
|
+
*/
|
|
8
|
+
exports.GetWalletPortfolioSchema = zod_1.z
|
|
9
|
+
.object({
|
|
10
|
+
walletAddress: zod_1.z
|
|
11
|
+
.string()
|
|
12
|
+
.describe("The wallet address to fetch portfolio for. Defaults is empty string, which will raise an error later if not provided."),
|
|
13
|
+
})
|
|
14
|
+
.strip()
|
|
15
|
+
.describe("Input schema for fetching wallet portfolio");
|