@coinbase/agentkit 0.5.0 → 0.6.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 +30 -0
- package/dist/action-providers/flaunch/constants.d.ts +1078 -0
- package/dist/action-providers/flaunch/constants.js +709 -0
- package/dist/action-providers/flaunch/flaunchActionProvider.d.ts +102 -0
- package/dist/action-providers/flaunch/flaunchActionProvider.js +519 -0
- package/dist/action-providers/flaunch/flaunchActionProvider.test.d.ts +1 -0
- package/dist/action-providers/flaunch/flaunchActionProvider.test.js +307 -0
- package/dist/action-providers/flaunch/index.d.ts +7 -0
- package/dist/action-providers/flaunch/index.js +23 -0
- package/dist/action-providers/flaunch/schemas.d.ts +77 -0
- package/dist/action-providers/flaunch/schemas.js +71 -0
- package/dist/action-providers/flaunch/types.d.ts +64 -0
- package/dist/action-providers/flaunch/types.js +2 -0
- package/dist/action-providers/flaunch/utils.d.ts +60 -0
- package/dist/action-providers/flaunch/utils.js +507 -0
- package/dist/action-providers/index.d.ts +2 -0
- package/dist/action-providers/index.js +2 -0
- package/dist/action-providers/onramp/index.d.ts +7 -0
- package/dist/action-providers/onramp/index.js +23 -0
- package/dist/action-providers/onramp/onrampActionProvider.d.ts +56 -0
- package/dist/action-providers/onramp/onrampActionProvider.js +109 -0
- package/dist/action-providers/onramp/onrampActionProvider.test.d.ts +1 -0
- package/dist/action-providers/onramp/onrampActionProvider.test.js +97 -0
- package/dist/action-providers/onramp/schemas.d.ts +12 -0
- package/dist/action-providers/onramp/schemas.js +15 -0
- package/dist/action-providers/onramp/types.d.ts +107 -0
- package/dist/action-providers/onramp/types.js +2 -0
- package/dist/action-providers/onramp/utils.d.ts +16 -0
- package/dist/action-providers/onramp/utils.js +56 -0
- package/dist/action-providers/onramp/version.d.ts +2 -0
- package/dist/action-providers/onramp/version.js +5 -0
- package/dist/wallet-providers/cdpWalletProvider.js +20 -10
- package/dist/wallet-providers/cdpWalletProvider.test.js +37 -3
- package/package.json +3 -2
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Onramp Action Provider
|
|
4
|
+
*
|
|
5
|
+
* This file contains the implementation of the OnrampActionProvider,
|
|
6
|
+
* which provides actions for onramp operations.
|
|
7
|
+
*
|
|
8
|
+
* @module onramp
|
|
9
|
+
*/
|
|
10
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
11
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
12
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
13
|
+
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;
|
|
14
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
15
|
+
};
|
|
16
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
17
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.onrampActionProvider = exports.OnrampActionProvider = void 0;
|
|
21
|
+
const zod_1 = require("zod");
|
|
22
|
+
const actionProvider_1 = require("../actionProvider");
|
|
23
|
+
const actionDecorator_1 = require("../actionDecorator");
|
|
24
|
+
const wallet_providers_1 = require("../../wallet-providers");
|
|
25
|
+
const schemas_1 = require("./schemas");
|
|
26
|
+
const utils_1 = require("./utils");
|
|
27
|
+
/**
|
|
28
|
+
* OnrampActionProvider provides actions for onramp operations.
|
|
29
|
+
*
|
|
30
|
+
* @description
|
|
31
|
+
* This provider is designed to work with EvmWalletProvider for blockchain interactions.
|
|
32
|
+
* It supports all evm networks.
|
|
33
|
+
*/
|
|
34
|
+
class OnrampActionProvider extends actionProvider_1.ActionProvider {
|
|
35
|
+
/**
|
|
36
|
+
* Constructor for the OnrampActionProvider.
|
|
37
|
+
*
|
|
38
|
+
* @param props - The props for the OnrampActionProvider
|
|
39
|
+
* @param props.projectId - The project ID for the OnrampActionProvider
|
|
40
|
+
*/
|
|
41
|
+
constructor(props) {
|
|
42
|
+
super("onramp", []);
|
|
43
|
+
this.projectId = props.projectId;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* This action provides a link to buy more cryptocurrency (ETH, USDC, or BTC) using fiat currency (regular money like USD).
|
|
47
|
+
*
|
|
48
|
+
* @param walletProvider - The wallet provider instance for blockchain interactions
|
|
49
|
+
* @param _ - The arguments for the action (not used)
|
|
50
|
+
* @returns A promise that resolves to a string describing the action result
|
|
51
|
+
*/
|
|
52
|
+
async getOnrampBuyUrl(walletProvider, _ = {}) {
|
|
53
|
+
const networkId = walletProvider.getNetwork().networkId;
|
|
54
|
+
if (!networkId) {
|
|
55
|
+
throw new Error("Network ID is not set");
|
|
56
|
+
}
|
|
57
|
+
const network = (0, utils_1.convertNetworkIdToOnrampNetworkId)(networkId);
|
|
58
|
+
if (!network) {
|
|
59
|
+
throw new Error("Network ID is not supported. Make sure you are using a supported mainnet network.");
|
|
60
|
+
}
|
|
61
|
+
return (0, utils_1.getOnrampBuyUrl)({
|
|
62
|
+
projectId: this.projectId,
|
|
63
|
+
addresses: {
|
|
64
|
+
[walletProvider.getAddress()]: [network],
|
|
65
|
+
},
|
|
66
|
+
defaultNetwork: network,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Checks if this provider supports the given network.
|
|
71
|
+
*
|
|
72
|
+
* @param network - The network to check support for
|
|
73
|
+
* @returns True if the network is supported
|
|
74
|
+
*/
|
|
75
|
+
supportsNetwork(network) {
|
|
76
|
+
return Boolean(network.networkId &&
|
|
77
|
+
(0, utils_1.convertNetworkIdToOnrampNetworkId)(network.networkId) !== null &&
|
|
78
|
+
network.protocolFamily === "evm");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.OnrampActionProvider = OnrampActionProvider;
|
|
82
|
+
__decorate([
|
|
83
|
+
(0, actionDecorator_1.CreateAction)({
|
|
84
|
+
name: "get_onramp_buy_url",
|
|
85
|
+
description: `
|
|
86
|
+
Get a URL to purchase more cryptocurrency when funds are low. This action provides a link to buy more
|
|
87
|
+
cryptocurrency, defaulting to ETH, using fiat currency (regular money like USD).
|
|
88
|
+
|
|
89
|
+
Use this when:
|
|
90
|
+
- You detect that the wallet has insufficient funds for a transaction
|
|
91
|
+
- You need to guide the user to purchase more cryptocurrency
|
|
92
|
+
- The user asks how to buy more crypto
|
|
93
|
+
|
|
94
|
+
The URL will direct to a secure Coinbase-powered purchase interface.
|
|
95
|
+
`,
|
|
96
|
+
schema: schemas_1.GetOnrampBuyUrlActionSchema,
|
|
97
|
+
}),
|
|
98
|
+
__metadata("design:type", Function),
|
|
99
|
+
__metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]),
|
|
100
|
+
__metadata("design:returntype", Promise)
|
|
101
|
+
], OnrampActionProvider.prototype, "getOnrampBuyUrl", null);
|
|
102
|
+
/**
|
|
103
|
+
* Factory function to create a new OnrampActionProvider instance.
|
|
104
|
+
*
|
|
105
|
+
* @param props - The props for the OnrampActionProvider
|
|
106
|
+
* @returns A new OnrampActionProvider instance
|
|
107
|
+
*/
|
|
108
|
+
const onrampActionProvider = (props) => new OnrampActionProvider(props);
|
|
109
|
+
exports.onrampActionProvider = onrampActionProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const onrampActionProvider_1 = require("./onrampActionProvider");
|
|
4
|
+
const schemas_1 = require("./schemas");
|
|
5
|
+
describe("OnrampActionProvider", () => {
|
|
6
|
+
const provider = new onrampActionProvider_1.OnrampActionProvider({
|
|
7
|
+
projectId: "test-project-id",
|
|
8
|
+
});
|
|
9
|
+
let mockWalletProvider;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
mockWalletProvider = {
|
|
12
|
+
getAddress: jest.fn().mockReturnValue("0x123"),
|
|
13
|
+
getBalance: jest.fn(),
|
|
14
|
+
getName: jest.fn(),
|
|
15
|
+
getNetwork: jest.fn().mockReturnValue({
|
|
16
|
+
protocolFamily: "evm",
|
|
17
|
+
networkId: "base-mainnet",
|
|
18
|
+
}),
|
|
19
|
+
nativeTransfer: jest.fn(),
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
describe("network support", () => {
|
|
23
|
+
it("should support valid EVM networks", () => {
|
|
24
|
+
expect(provider.supportsNetwork({
|
|
25
|
+
networkId: "base-mainnet",
|
|
26
|
+
protocolFamily: "evm",
|
|
27
|
+
})).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it("should not support invalid EVM networks, such as testnets", () => {
|
|
30
|
+
expect(provider.supportsNetwork({
|
|
31
|
+
networkId: "base-sepolia",
|
|
32
|
+
protocolFamily: "evm",
|
|
33
|
+
})).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
it("should not support other protocol families", () => {
|
|
36
|
+
expect(provider.supportsNetwork({
|
|
37
|
+
protocolFamily: "other-protocol-family",
|
|
38
|
+
})).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it("should handle invalid network objects", () => {
|
|
41
|
+
expect(provider.supportsNetwork({})).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe("action validation", () => {
|
|
45
|
+
it("should validate getOnrampBuyUrl schema", () => {
|
|
46
|
+
const validInput = {};
|
|
47
|
+
const parseResult = schemas_1.GetOnrampBuyUrlActionSchema.safeParse(validInput);
|
|
48
|
+
expect(parseResult.success).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("getOnrampBuyUrl", () => {
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
mockWalletProvider.getAddress.mockReturnValue("0x123");
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Parses URL search parameters from a URL string.
|
|
57
|
+
*
|
|
58
|
+
* @param url - The URL string to parse parameters from
|
|
59
|
+
* @returns The parsed URL search parameters
|
|
60
|
+
*/
|
|
61
|
+
function parseUrlParams(url) {
|
|
62
|
+
const urlObj = new URL(url);
|
|
63
|
+
return urlObj.searchParams;
|
|
64
|
+
}
|
|
65
|
+
it("should execute getOnrampBuyUrl with wallet provider", async () => {
|
|
66
|
+
const result = await provider.getOnrampBuyUrl(mockWalletProvider, {});
|
|
67
|
+
const url = new URL(result);
|
|
68
|
+
const params = parseUrlParams(result);
|
|
69
|
+
// Verify base URL
|
|
70
|
+
expect(url.origin + url.pathname).toBe("https://pay.coinbase.com/buy");
|
|
71
|
+
// Verify all expected parameters are present with correct values
|
|
72
|
+
expect(params.get("appId")).toBe("test-project-id");
|
|
73
|
+
expect(params.get("defaultNetwork")).toBe("base");
|
|
74
|
+
// Verify address configuration
|
|
75
|
+
const addressConfig = JSON.parse(params.get("addresses") || "{}");
|
|
76
|
+
expect(addressConfig).toEqual({
|
|
77
|
+
"0x123": ["base"],
|
|
78
|
+
});
|
|
79
|
+
expect(mockWalletProvider.getNetwork).toHaveBeenCalled();
|
|
80
|
+
expect(mockWalletProvider.getAddress).toHaveBeenCalled();
|
|
81
|
+
});
|
|
82
|
+
it("should throw error for unsupported network", async () => {
|
|
83
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
84
|
+
protocolFamily: "evm",
|
|
85
|
+
networkId: "unsupported-network",
|
|
86
|
+
});
|
|
87
|
+
await expect(provider.getOnrampBuyUrl(mockWalletProvider, {})).rejects.toThrow("Network ID is not supported. Make sure you are using a supported mainnet network.");
|
|
88
|
+
});
|
|
89
|
+
it("should throw error when network ID is not set", async () => {
|
|
90
|
+
mockWalletProvider.getNetwork.mockReturnValue({
|
|
91
|
+
protocolFamily: "evm",
|
|
92
|
+
networkId: undefined,
|
|
93
|
+
});
|
|
94
|
+
await expect(provider.getOnrampBuyUrl(mockWalletProvider, {})).rejects.toThrow("Network ID is not set");
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Action schemas for the onramp action provider.
|
|
4
|
+
*
|
|
5
|
+
* This file contains the Zod schemas that define the shape and validation
|
|
6
|
+
* rules for action parameters in the onramp action provider.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Example action schema demonstrating various field types and validations.
|
|
10
|
+
* Replace or modify this with your actual action schemas.
|
|
11
|
+
*/
|
|
12
|
+
export declare const GetOnrampBuyUrlActionSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetOnrampBuyUrlActionSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
/**
|
|
6
|
+
* Action schemas for the onramp action provider.
|
|
7
|
+
*
|
|
8
|
+
* This file contains the Zod schemas that define the shape and validation
|
|
9
|
+
* rules for action parameters in the onramp action provider.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Example action schema demonstrating various field types and validations.
|
|
13
|
+
* Replace or modify this with your actual action schemas.
|
|
14
|
+
*/
|
|
15
|
+
exports.GetOnrampBuyUrlActionSchema = zod_1.z.object({});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props used to get an Onramp buy URL by directly providing a CDP project ID.
|
|
3
|
+
* See https://docs.cdp.coinbase.com/onramp/docs/api-initializing#generating-the-coinbase-onramp-buysell-url
|
|
4
|
+
*
|
|
5
|
+
* Note: exported as public Type
|
|
6
|
+
*/
|
|
7
|
+
export type GetOnrampUrlWithProjectIdParams = {
|
|
8
|
+
/**
|
|
9
|
+
* The Project ID of your CDP project created at https://portal.cdp.coinbase.com/
|
|
10
|
+
* This must be provided if you don't provide a sessionToken.
|
|
11
|
+
*/
|
|
12
|
+
projectId: string;
|
|
13
|
+
sessionToken?: never;
|
|
14
|
+
/**
|
|
15
|
+
* The addresses that the customer's funds should be delivered to.
|
|
16
|
+
*
|
|
17
|
+
* Each entry in the record represents a wallet address and the networks it is valid for. There should only be a
|
|
18
|
+
* single address for each network your app supports. Users will be able to buy/send any asset supported by any of
|
|
19
|
+
* the networks you specify. See the assets param if you want to restrict the available assets.
|
|
20
|
+
*
|
|
21
|
+
* Some common examples:
|
|
22
|
+
*
|
|
23
|
+
* Support all assets that are available for sending on the base network, only on the base network:
|
|
24
|
+
*
|
|
25
|
+
* `{ "0x1": ["base"] }`
|
|
26
|
+
*/
|
|
27
|
+
addresses: Record<string, string[]>;
|
|
28
|
+
/**
|
|
29
|
+
* This optional parameter will restrict the assets available for the user to buy/send. It acts as a filter on the
|
|
30
|
+
* networks specified in the {addresses} param.
|
|
31
|
+
*
|
|
32
|
+
* Some common examples:
|
|
33
|
+
*
|
|
34
|
+
* Support only USDC on either the base network or the ethereum network:
|
|
35
|
+
*
|
|
36
|
+
* `addresses: { "0x1": ["base", "ethereum"] }, assets: ["USDC"]`
|
|
37
|
+
*
|
|
38
|
+
* The values in this list can either be asset symbols like BTC, ETH, or asset UUIDs that you can get from the Buy
|
|
39
|
+
* Options API {@link https://docs.cdp.coinbase.com/onramp/docs/api-configurations/#buy-options}.
|
|
40
|
+
*/
|
|
41
|
+
assets?: string[];
|
|
42
|
+
} & GetOnrampBuyUrlOptionalProps;
|
|
43
|
+
/**
|
|
44
|
+
* Props used to get an Onramp buy URL using a session token created using the Onramp session token API.
|
|
45
|
+
* See https://docs.cdp.coinbase.com/onramp/docs/api-initializing#getting-an-coinbase-onramp-buysell-session-token
|
|
46
|
+
*
|
|
47
|
+
* Note: exported as public Type
|
|
48
|
+
*/
|
|
49
|
+
export type GetOnrampUrlWithSessionTokenParams = {
|
|
50
|
+
/**
|
|
51
|
+
* A session token create using the Onramp session token API. The token will be linked to the project ID, addresses,
|
|
52
|
+
* and assets params provided in the create session token API request.
|
|
53
|
+
*/
|
|
54
|
+
sessionToken: string;
|
|
55
|
+
projectId?: never;
|
|
56
|
+
addresses?: never;
|
|
57
|
+
assets?: never;
|
|
58
|
+
} & GetOnrampBuyUrlOptionalProps;
|
|
59
|
+
/**
|
|
60
|
+
* The optional properties that can be used to create an Onramp buy URL.
|
|
61
|
+
*/
|
|
62
|
+
type GetOnrampBuyUrlOptionalProps = {
|
|
63
|
+
/**
|
|
64
|
+
* If specified, this asset will be automatically selected for the user in the Onramp UI. Should be a valid asset
|
|
65
|
+
* symbol e.g. BTC, ETH, USDC.
|
|
66
|
+
*/
|
|
67
|
+
defaultAsset?: string;
|
|
68
|
+
/**
|
|
69
|
+
* If specified, this network will be automatically selected for the user in the Onramp UI. Should be a valid network
|
|
70
|
+
* name in lower case e.g. ethereum, base.
|
|
71
|
+
*/
|
|
72
|
+
defaultNetwork?: string;
|
|
73
|
+
/**
|
|
74
|
+
* A unique identifier that will be associated with any transactions created by the user during their Onramp session.
|
|
75
|
+
* You can use this with the Transaction Status API to check the status of the user's transaction.
|
|
76
|
+
* See https://docs.cdp.coinbase.com/onramp/docs/api-reporting#buy-transaction-status
|
|
77
|
+
*/
|
|
78
|
+
partnerUserId?: string;
|
|
79
|
+
/**
|
|
80
|
+
* This amount will be used to pre-fill the amount of crypto the user is buying or sending. The user can choose to
|
|
81
|
+
* change this amount in the UI. Only one of presetCryptoAmount or presetFiatAmount should be provided.
|
|
82
|
+
*/
|
|
83
|
+
presetCryptoAmount?: number;
|
|
84
|
+
/**
|
|
85
|
+
* This amount will be used to pre-fill the fiat value of the crypto the user is buying or sending. The user can
|
|
86
|
+
* choose to change this amount in the UI. Only one of presetCryptoAmount or presetFiatAmount should be provided.
|
|
87
|
+
*/
|
|
88
|
+
presetFiatAmount?: number;
|
|
89
|
+
/**
|
|
90
|
+
* The default payment method that will be selected for the user in the Onramp UI. Should be one of the payment methods
|
|
91
|
+
*/
|
|
92
|
+
defaultPaymentMethod?: string;
|
|
93
|
+
/**
|
|
94
|
+
* The currency code of the fiat amount provided in the presetFiatAmount param e.g. USD, CAD, EUR.
|
|
95
|
+
*/
|
|
96
|
+
fiatCurrency?: string;
|
|
97
|
+
/**
|
|
98
|
+
* A URL that the user will be automatically redirected to after a successful buy/send. The domain must match a domain
|
|
99
|
+
* on the domain allowlist in Coinbase Developer Platform (https://portal.cdp.coinbase.com/products/onramp).
|
|
100
|
+
*/
|
|
101
|
+
redirectUrl?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The name of the component that is calling the Onramp buy URL. This will be used for analytics.
|
|
104
|
+
*/
|
|
105
|
+
originComponentName?: string;
|
|
106
|
+
};
|
|
107
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GetOnrampUrlWithProjectIdParams, GetOnrampUrlWithSessionTokenParams } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Builds a Coinbase Onramp buy URL using the provided parameters.
|
|
4
|
+
*
|
|
5
|
+
* @param props - Configuration options for the Onramp buy URL
|
|
6
|
+
* @param props.projectId - A projectId generated in the Coinbase Developer Portal
|
|
7
|
+
* @returns The generated Onramp buy URL
|
|
8
|
+
*/
|
|
9
|
+
export declare function getOnrampBuyUrl({ projectId, ...props }: GetOnrampUrlWithProjectIdParams | GetOnrampUrlWithSessionTokenParams): string;
|
|
10
|
+
/**
|
|
11
|
+
* Converts a network ID to an Onramp network ID.
|
|
12
|
+
*
|
|
13
|
+
* @param networkId - The network ID to convert
|
|
14
|
+
* @returns The Onramp network ID or null if the network ID is not supported
|
|
15
|
+
*/
|
|
16
|
+
export declare const convertNetworkIdToOnrampNetworkId: (networkId: string) => string | null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertNetworkIdToOnrampNetworkId = void 0;
|
|
4
|
+
exports.getOnrampBuyUrl = getOnrampBuyUrl;
|
|
5
|
+
const version_1 = require("./version");
|
|
6
|
+
/**
|
|
7
|
+
* Builds a Coinbase Onramp buy URL using the provided parameters.
|
|
8
|
+
*
|
|
9
|
+
* @param props - Configuration options for the Onramp buy URL
|
|
10
|
+
* @param props.projectId - A projectId generated in the Coinbase Developer Portal
|
|
11
|
+
* @returns The generated Onramp buy URL
|
|
12
|
+
*/
|
|
13
|
+
function getOnrampBuyUrl({ projectId, ...props }) {
|
|
14
|
+
const url = new URL(version_1.ONRAMP_BUY_URL);
|
|
15
|
+
if (projectId !== undefined) {
|
|
16
|
+
// Coinbase Onramp requires projectId to be passed as appId
|
|
17
|
+
url.searchParams.append("appId", projectId);
|
|
18
|
+
}
|
|
19
|
+
for (const key of Object.keys(props)) {
|
|
20
|
+
const value = props[key];
|
|
21
|
+
if (value !== undefined) {
|
|
22
|
+
if (["string", "number", "boolean"].includes(typeof value)) {
|
|
23
|
+
url.searchParams.append(key, value.toString());
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
url.searchParams.append(key, JSON.stringify(value));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
url.searchParams.append("sdkVersion", `onchainkit@${version_1.VERSION}`);
|
|
31
|
+
url.searchParams.sort();
|
|
32
|
+
return url.toString();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Converts a network ID to an Onramp network ID.
|
|
36
|
+
*
|
|
37
|
+
* @param networkId - The network ID to convert
|
|
38
|
+
* @returns The Onramp network ID or null if the network ID is not supported
|
|
39
|
+
*/
|
|
40
|
+
const convertNetworkIdToOnrampNetworkId = (networkId) => {
|
|
41
|
+
switch (networkId) {
|
|
42
|
+
case "base-mainnet":
|
|
43
|
+
return "base";
|
|
44
|
+
case "ethereum-mainnet":
|
|
45
|
+
return "ethereum";
|
|
46
|
+
case "polygon-mainnet":
|
|
47
|
+
return "polygon";
|
|
48
|
+
case "optimism-mainnet":
|
|
49
|
+
return "optimism";
|
|
50
|
+
case "arbitrum-mainnet":
|
|
51
|
+
return "arbitrum";
|
|
52
|
+
default:
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.convertNetworkIdToOnrampNetworkId = convertNetworkIdToOnrampNetworkId;
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
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");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _CdpWalletProvider_cdpWallet, _CdpWalletProvider_address, _CdpWalletProvider_network, _CdpWalletProvider_publicClient, _CdpWalletProvider_gasLimitMultiplier, _CdpWalletProvider_feePerGasMultiplier;
|
|
13
|
+
var _CdpWalletProvider_cdpWallet, _CdpWalletProvider_address, _CdpWalletProvider_network, _CdpWalletProvider_publicClient, _CdpWalletProvider_gasLimitMultiplier, _CdpWalletProvider_feePerGasMultiplier, _CdpWalletProvider_transactionQueue;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.CdpWalletProvider = void 0;
|
|
16
16
|
const package_json_1 = require("../../package.json");
|
|
@@ -37,6 +37,7 @@ class CdpWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
|
|
|
37
37
|
_CdpWalletProvider_publicClient.set(this, void 0);
|
|
38
38
|
_CdpWalletProvider_gasLimitMultiplier.set(this, void 0);
|
|
39
39
|
_CdpWalletProvider_feePerGasMultiplier.set(this, void 0);
|
|
40
|
+
_CdpWalletProvider_transactionQueue.set(this, void 0);
|
|
40
41
|
__classPrivateFieldSet(this, _CdpWalletProvider_cdpWallet, config.wallet, "f");
|
|
41
42
|
__classPrivateFieldSet(this, _CdpWalletProvider_address, config.address, "f");
|
|
42
43
|
__classPrivateFieldSet(this, _CdpWalletProvider_network, config.network, "f");
|
|
@@ -165,14 +166,22 @@ class CdpWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
|
|
|
165
166
|
if (!__classPrivateFieldGet(this, _CdpWalletProvider_cdpWallet, "f")) {
|
|
166
167
|
throw new Error("Wallet not initialized");
|
|
167
168
|
}
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
169
|
+
const sendPromise = (async () => {
|
|
170
|
+
if (__classPrivateFieldGet(this, _CdpWalletProvider_transactionQueue, "f"))
|
|
171
|
+
await __classPrivateFieldGet(this, _CdpWalletProvider_transactionQueue, "f");
|
|
172
|
+
const preparedTransaction = await this.prepareTransaction(transaction.to, transaction.value, transaction.data);
|
|
173
|
+
const signature = await this.signTransaction({
|
|
174
|
+
...preparedTransaction,
|
|
175
|
+
});
|
|
176
|
+
const signedPayload = await this.addSignatureAndSerialize(preparedTransaction, signature);
|
|
177
|
+
const externalAddress = new coinbase_sdk_1.ExternalAddress(__classPrivateFieldGet(this, _CdpWalletProvider_cdpWallet, "f").getNetworkId(), __classPrivateFieldGet(this, _CdpWalletProvider_address, "f"));
|
|
178
|
+
const tx = await externalAddress.broadcastExternalTransaction(signedPayload.slice(2));
|
|
179
|
+
return tx.transactionHash;
|
|
180
|
+
})();
|
|
181
|
+
__classPrivateFieldSet(this, _CdpWalletProvider_transactionQueue, sendPromise
|
|
182
|
+
.then(txHash => this.waitForTransactionReceipt(txHash))
|
|
183
|
+
.catch(() => { }), "f");
|
|
184
|
+
return await sendPromise;
|
|
176
185
|
}
|
|
177
186
|
/**
|
|
178
187
|
* Prepares a transaction.
|
|
@@ -188,6 +197,7 @@ class CdpWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
|
|
|
188
197
|
}
|
|
189
198
|
const nonce = await __classPrivateFieldGet(this, _CdpWalletProvider_publicClient, "f").getTransactionCount({
|
|
190
199
|
address: __classPrivateFieldGet(this, _CdpWalletProvider_address, "f"),
|
|
200
|
+
blockTag: "pending",
|
|
191
201
|
});
|
|
192
202
|
const feeData = await __classPrivateFieldGet(this, _CdpWalletProvider_publicClient, "f").estimateFeesPerGas();
|
|
193
203
|
const maxFeePerGas = (0, utils_1.applyGasMultiplier)(feeData.maxFeePerGas, __classPrivateFieldGet(this, _CdpWalletProvider_feePerGasMultiplier, "f"));
|
|
@@ -418,4 +428,4 @@ class CdpWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
|
|
|
418
428
|
}
|
|
419
429
|
}
|
|
420
430
|
exports.CdpWalletProvider = CdpWalletProvider;
|
|
421
|
-
_CdpWalletProvider_cdpWallet = new WeakMap(), _CdpWalletProvider_address = new WeakMap(), _CdpWalletProvider_network = new WeakMap(), _CdpWalletProvider_publicClient = new WeakMap(), _CdpWalletProvider_gasLimitMultiplier = new WeakMap(), _CdpWalletProvider_feePerGasMultiplier = new WeakMap();
|
|
431
|
+
_CdpWalletProvider_cdpWallet = new WeakMap(), _CdpWalletProvider_address = new WeakMap(), _CdpWalletProvider_network = new WeakMap(), _CdpWalletProvider_publicClient = new WeakMap(), _CdpWalletProvider_gasLimitMultiplier = new WeakMap(), _CdpWalletProvider_feePerGasMultiplier = new WeakMap(), _CdpWalletProvider_transactionQueue = new WeakMap();
|
|
@@ -122,6 +122,9 @@ const MOCK_NETWORK = {
|
|
|
122
122
|
protocolFamily: "evm",
|
|
123
123
|
networkId: MOCK_NETWORK_ID,
|
|
124
124
|
};
|
|
125
|
+
const MOCK_TRANSACTION_RECEIPT = {
|
|
126
|
+
transactionHash: MOCK_TRANSACTION_HASH,
|
|
127
|
+
};
|
|
125
128
|
describe("CdpWalletProvider", () => {
|
|
126
129
|
let provider;
|
|
127
130
|
beforeEach(async () => {
|
|
@@ -154,9 +157,7 @@ describe("CdpWalletProvider", () => {
|
|
|
154
157
|
});
|
|
155
158
|
jest.spyOn(coinbase_sdk_1.Wallet, "import").mockResolvedValue(mockWalletObj);
|
|
156
159
|
jest.spyOn(coinbase_sdk_1.Wallet, "create").mockResolvedValue(mockWalletObj);
|
|
157
|
-
mockPublicClient.waitForTransactionReceipt.mockResolvedValue(
|
|
158
|
-
transactionHash: MOCK_TRANSACTION_HASH,
|
|
159
|
-
});
|
|
160
|
+
mockPublicClient.waitForTransactionReceipt.mockResolvedValue(MOCK_TRANSACTION_RECEIPT);
|
|
160
161
|
mockPublicClient.readContract.mockResolvedValue("mock_result");
|
|
161
162
|
mockPublicClient.getTransactionCount.mockResolvedValue(1);
|
|
162
163
|
mockPublicClient.estimateFeesPerGas.mockResolvedValue({
|
|
@@ -323,6 +324,39 @@ describe("CdpWalletProvider", () => {
|
|
|
323
324
|
expect(mockWalletObj.createPayloadSignature).toHaveBeenCalled();
|
|
324
325
|
expect(txHash).toBe(MOCK_TRANSACTION_HASH);
|
|
325
326
|
});
|
|
327
|
+
it("should wait for the first transfer before sending another one", async () => {
|
|
328
|
+
const validSignature = "0x" + "1".repeat(64) + "2".repeat(64) + "01"; // r, s, v format (130 chars + 0x prefix)
|
|
329
|
+
const mockSignature = {
|
|
330
|
+
model: {},
|
|
331
|
+
getId: jest.fn().mockReturnValue("signature-id"),
|
|
332
|
+
getWalletId: jest.fn().mockReturnValue("mock-wallet-id"),
|
|
333
|
+
getAddressId: jest.fn().mockReturnValue(MOCK_ADDRESS),
|
|
334
|
+
getNetworkId: jest.fn().mockReturnValue(MOCK_NETWORK_ID),
|
|
335
|
+
getSignature: jest.fn().mockReturnValue(validSignature),
|
|
336
|
+
getPayload: jest.fn().mockReturnValue("0xpayload"),
|
|
337
|
+
getEncodedPayload: jest.fn().mockReturnValue("0xencodedpayload"),
|
|
338
|
+
getStatus: jest.fn().mockReturnValue("completed"),
|
|
339
|
+
};
|
|
340
|
+
mockWalletObj.createPayloadSignature.mockResolvedValue(mockSignature);
|
|
341
|
+
const transaction = {
|
|
342
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
343
|
+
value: BigInt(1000000000000000000),
|
|
344
|
+
};
|
|
345
|
+
mockPublicClient.waitForTransactionReceipt.mockImplementationOnce(async () => {
|
|
346
|
+
await new Promise(resolve => setTimeout(resolve, 20));
|
|
347
|
+
return MOCK_TRANSACTION_RECEIPT;
|
|
348
|
+
});
|
|
349
|
+
const txHash1 = await provider.sendTransaction(transaction);
|
|
350
|
+
expect(mockWalletObj.createPayloadSignature).toHaveBeenCalledTimes(1);
|
|
351
|
+
expect(txHash1).toBe(MOCK_TRANSACTION_HASH);
|
|
352
|
+
expect(mockPublicClient.waitForTransactionReceipt).toHaveBeenCalledTimes(1);
|
|
353
|
+
const awaitReceiptPromise = mockPublicClient.waitForTransactionReceipt.mock.results[0]
|
|
354
|
+
.value;
|
|
355
|
+
const secondTxHashPromise = provider.sendTransaction(transaction);
|
|
356
|
+
const race = Promise.race([awaitReceiptPromise, secondTxHashPromise]);
|
|
357
|
+
expect(await race).toStrictEqual(MOCK_TRANSACTION_RECEIPT);
|
|
358
|
+
expect(await secondTxHashPromise).toBe(MOCK_TRANSACTION_HASH);
|
|
359
|
+
});
|
|
326
360
|
it("should execute a native transfer", async () => {
|
|
327
361
|
const to = "0x1234567890123456789012345678901234567890";
|
|
328
362
|
const value = "1.0";
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@coinbase/agentkit",
|
|
3
3
|
"description": "Coinbase AgentKit core primitives",
|
|
4
4
|
"repository": "https://github.com/coinbase/agentkit",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.6.0",
|
|
6
6
|
"author": "Coinbase Inc.",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"main": "dist/index.js",
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
"ts-jest": "^29.2.5",
|
|
58
58
|
"tsd": "^0.31.2",
|
|
59
59
|
"tsx": "^4.7.1",
|
|
60
|
-
"typescript": "^5.7.2"
|
|
60
|
+
"typescript": "^5.7.2",
|
|
61
|
+
"yargs": "^17.7.2"
|
|
61
62
|
},
|
|
62
63
|
"exports": {
|
|
63
64
|
".": {
|