@pincerpay/solana 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/kora/config.d.ts +20 -0
- package/dist/kora/config.d.ts.map +1 -0
- package/dist/kora/config.js +20 -0
- package/dist/kora/config.js.map +1 -0
- package/dist/kora/index.d.ts +5 -0
- package/dist/kora/index.d.ts.map +1 -0
- package/dist/kora/index.js +3 -0
- package/dist/kora/index.js.map +1 -0
- package/dist/kora/signer.d.ts +52 -0
- package/dist/kora/signer.d.ts.map +1 -0
- package/dist/kora/signer.js +151 -0
- package/dist/kora/signer.js.map +1 -0
- package/dist/squads/accounts.d.ts +19 -0
- package/dist/squads/accounts.d.ts.map +1 -0
- package/dist/squads/accounts.js +52 -0
- package/dist/squads/accounts.js.map +1 -0
- package/dist/squads/index.d.ts +6 -0
- package/dist/squads/index.d.ts.map +1 -0
- package/dist/squads/index.js +6 -0
- package/dist/squads/index.js.map +1 -0
- package/dist/squads/instructions.d.ts +43 -0
- package/dist/squads/instructions.d.ts.map +1 -0
- package/dist/squads/instructions.js +163 -0
- package/dist/squads/instructions.js.map +1 -0
- package/dist/squads/spending.d.ts +24 -0
- package/dist/squads/spending.d.ts.map +1 -0
- package/dist/squads/spending.js +54 -0
- package/dist/squads/spending.js.map +1 -0
- package/dist/squads/types.d.ts +41 -0
- package/dist/squads/types.d.ts.map +1 -0
- package/dist/squads/types.js +15 -0
- package/dist/squads/types.js.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PincerPay
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# @pincerpay/solana
|
|
2
|
+
|
|
3
|
+
Solana infrastructure integrations for PincerPay: Kora gasless transactions and Squads SPN smart accounts.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pincerpay/solana
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Kora (Gasless Transactions)
|
|
12
|
+
|
|
13
|
+
Agents pay transaction fees in USDC instead of SOL via Kora signer nodes.
|
|
14
|
+
|
|
15
|
+
### Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { createKoraClient, createKoraFacilitatorSvmSigner } from "@pincerpay/solana/kora";
|
|
19
|
+
|
|
20
|
+
// Low-level client
|
|
21
|
+
const kora = createKoraClient({
|
|
22
|
+
rpcUrl: "https://your-kora-node.example.com",
|
|
23
|
+
apiKey: "optional-api-key",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const feePayer = await kora.getFeePayer();
|
|
27
|
+
|
|
28
|
+
// x402 facilitator integration
|
|
29
|
+
const signer = createKoraFacilitatorSvmSigner({
|
|
30
|
+
config: { rpcUrl: "https://your-kora-node.example.com" },
|
|
31
|
+
rpcUrls: { "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1": "https://api.devnet.solana.com" },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
await signer.init(); // Fetches fee payer address
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### API Reference
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
interface KoraConfig {
|
|
41
|
+
rpcUrl: string;
|
|
42
|
+
apiKey?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function createKoraClient(config: KoraConfig): KoraRpcClient;
|
|
46
|
+
|
|
47
|
+
function createKoraFacilitatorSvmSigner(options: {
|
|
48
|
+
config: KoraConfig;
|
|
49
|
+
rpcUrls?: Record<string, string>;
|
|
50
|
+
}): FacilitatorSvmSigner & { init(): Promise<void> };
|
|
51
|
+
|
|
52
|
+
function parseKoraConfig(
|
|
53
|
+
env: Record<string, string | undefined>
|
|
54
|
+
): KoraConfig | null;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Squads SPN (Smart Accounts)
|
|
58
|
+
|
|
59
|
+
Decentralized policy co-signer for agent sub-accounts with on-chain spending limits.
|
|
60
|
+
|
|
61
|
+
### Quick Start
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import {
|
|
65
|
+
deriveSmartAccountPda,
|
|
66
|
+
createSpendingLimit,
|
|
67
|
+
checkSpendingLimit,
|
|
68
|
+
SpendingLimitPeriod,
|
|
69
|
+
} from "@pincerpay/solana/squads";
|
|
70
|
+
|
|
71
|
+
// Derive smart account PDA
|
|
72
|
+
const [smartAccountPda] = await deriveSmartAccountPda(creatorAddress, 0);
|
|
73
|
+
|
|
74
|
+
// Create a daily spending limit
|
|
75
|
+
const ix = await createSpendingLimit(
|
|
76
|
+
{
|
|
77
|
+
smartAccountPda,
|
|
78
|
+
mint: usdcMintAddress,
|
|
79
|
+
amount: 10_000_000n, // 10 USDC
|
|
80
|
+
period: SpendingLimitPeriod.Day,
|
|
81
|
+
members: [agentAddress],
|
|
82
|
+
destinations: [merchantAddress],
|
|
83
|
+
},
|
|
84
|
+
0, // spending limit index
|
|
85
|
+
authorityAddress
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Check remaining allowance
|
|
89
|
+
const limit = await checkSpendingLimit(smartAccountPda, 0, rpcUrl);
|
|
90
|
+
// { exists: true, remainingAmount: 8_000_000n, period: "Day" }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### API Reference
|
|
94
|
+
|
|
95
|
+
#### PDA Derivation
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
async function deriveSmartAccountPda(
|
|
99
|
+
creator: Address, accountIndex: number, programId?: Address
|
|
100
|
+
): Promise<[Address, number]>;
|
|
101
|
+
|
|
102
|
+
async function deriveSettingsPda(
|
|
103
|
+
smartAccountPda: Address, programId?: Address
|
|
104
|
+
): Promise<[Address, number]>;
|
|
105
|
+
|
|
106
|
+
async function deriveSpendingLimitPda(
|
|
107
|
+
smartAccountPda: Address, spendingLimitIndex: number, programId?: Address
|
|
108
|
+
): Promise<[Address, number]>;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Spending Limit Management
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
async function createSpendingLimit(
|
|
115
|
+
config: SpendingLimitConfig, spendingLimitIndex: number, authority: Address
|
|
116
|
+
): Promise<Instruction>;
|
|
117
|
+
|
|
118
|
+
async function checkSpendingLimit(
|
|
119
|
+
smartAccountPda: Address, spendingLimitIndex: number, rpcUrl: string
|
|
120
|
+
): Promise<{ exists: boolean; remainingAmount?: bigint; period?: SpendingLimitPeriod } | null>;
|
|
121
|
+
|
|
122
|
+
async function revokeSpendingLimit(
|
|
123
|
+
smartAccountPda: Address, spendingLimitIndex: number, authority: Address, rentCollector: Address
|
|
124
|
+
): Promise<Instruction>;
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### Types
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
enum SpendingLimitPeriod {
|
|
131
|
+
OneTime = 0,
|
|
132
|
+
Day = 1,
|
|
133
|
+
Week = 2,
|
|
134
|
+
Month = 3,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface SpendingLimitConfig {
|
|
138
|
+
smartAccountPda: Address;
|
|
139
|
+
mint: Address;
|
|
140
|
+
amount: bigint;
|
|
141
|
+
period: SpendingLimitPeriod;
|
|
142
|
+
members: Address[];
|
|
143
|
+
destinations: Address[];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface SmartAccountConfig {
|
|
147
|
+
creator: Address;
|
|
148
|
+
accountIndex: number;
|
|
149
|
+
members: Address[];
|
|
150
|
+
threshold: number;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const SQUADS_PROGRAM_ID = "SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG";
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Common Patterns
|
|
157
|
+
|
|
158
|
+
### Kora + Squads together
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { createKoraFacilitatorSvmSigner } from "@pincerpay/solana/kora";
|
|
162
|
+
import { deriveSmartAccountPda, checkSpendingLimit } from "@pincerpay/solana/squads";
|
|
163
|
+
|
|
164
|
+
// Agent pays gas in USDC (Kora) + has on-chain spending limits (Squads)
|
|
165
|
+
const signer = createKoraFacilitatorSvmSigner({ config: koraConfig });
|
|
166
|
+
const [smartAccount] = await deriveSmartAccountPda(creator, 0);
|
|
167
|
+
const limit = await checkSpendingLimit(smartAccount, 0, rpcUrl);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Anti-Patterns
|
|
171
|
+
|
|
172
|
+
### Don't skip `signer.init()` for Kora
|
|
173
|
+
|
|
174
|
+
The Kora signer must call `init()` before use — it fetches the fee payer address from the Kora node.
|
|
175
|
+
|
|
176
|
+
### Don't use Squads on EVM
|
|
177
|
+
|
|
178
|
+
Squads SPN is Solana-only. For EVM agent permissions, use ERC-7715 session keys instead.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const koraConfigSchema: z.ZodObject<{
|
|
3
|
+
/** Kora RPC endpoint URL */
|
|
4
|
+
rpcUrl: z.ZodString;
|
|
5
|
+
/** Kora API key for authentication (optional, depends on Kora node config) */
|
|
6
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
rpcUrl: string;
|
|
9
|
+
apiKey?: string | undefined;
|
|
10
|
+
}, {
|
|
11
|
+
rpcUrl: string;
|
|
12
|
+
apiKey?: string | undefined;
|
|
13
|
+
}>;
|
|
14
|
+
export type KoraConfig = z.infer<typeof koraConfigSchema>;
|
|
15
|
+
/**
|
|
16
|
+
* Parse Kora configuration from environment variables.
|
|
17
|
+
* Returns null if KORA_RPC_URL is not set.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseKoraConfig(env: Record<string, string | undefined>): KoraConfig | null;
|
|
20
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/kora/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;IAC3B,4BAA4B;;IAE5B,8EAA8E;;;;;;;;EAE9E,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,IAAI,CAM1F"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const koraConfigSchema = z.object({
|
|
3
|
+
/** Kora RPC endpoint URL */
|
|
4
|
+
rpcUrl: z.string().url(),
|
|
5
|
+
/** Kora API key for authentication (optional, depends on Kora node config) */
|
|
6
|
+
apiKey: z.string().optional(),
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* Parse Kora configuration from environment variables.
|
|
10
|
+
* Returns null if KORA_RPC_URL is not set.
|
|
11
|
+
*/
|
|
12
|
+
export function parseKoraConfig(env) {
|
|
13
|
+
if (!env.KORA_RPC_URL)
|
|
14
|
+
return null;
|
|
15
|
+
return koraConfigSchema.parse({
|
|
16
|
+
rpcUrl: env.KORA_RPC_URL,
|
|
17
|
+
apiKey: env.KORA_API_KEY,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/kora/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,4BAA4B;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACxB,8EAA8E;IAC9E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAuC;IACrE,IAAI,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,gBAAgB,CAAC,KAAK,CAAC;QAC5B,MAAM,EAAE,GAAG,CAAC,YAAY;QACxB,MAAM,EAAE,GAAG,CAAC,YAAY;KACzB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createKoraFacilitatorSvmSigner, createKoraClient } from "./signer.js";
|
|
2
|
+
export type { KoraRpcClient } from "./signer.js";
|
|
3
|
+
export { parseKoraConfig, koraConfigSchema } from "./config.js";
|
|
4
|
+
export type { KoraConfig } from "./config.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kora/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/kora/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { FacilitatorSvmSigner } from "@x402/svm";
|
|
2
|
+
import type { KoraConfig } from "./config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Kora RPC client interface — minimal subset of JSON-RPC methods we use.
|
|
5
|
+
* Kora exposes standard Solana RPC + custom methods for gasless transactions.
|
|
6
|
+
*/
|
|
7
|
+
interface KoraPayerSignerResult {
|
|
8
|
+
signer_address: string;
|
|
9
|
+
payment_address: string;
|
|
10
|
+
}
|
|
11
|
+
interface KoraSignResult {
|
|
12
|
+
signature: string;
|
|
13
|
+
signed_transaction: string;
|
|
14
|
+
signer_pubkey: string;
|
|
15
|
+
}
|
|
16
|
+
interface KoraRpcClient {
|
|
17
|
+
/** Fetch the Kora signer node's payer signer info (address + payment destination) */
|
|
18
|
+
getPayerSigner(): Promise<KoraPayerSignerResult>;
|
|
19
|
+
/** Sign a base64-encoded transaction with the Kora fee payer */
|
|
20
|
+
signTransaction(params: {
|
|
21
|
+
transaction: string;
|
|
22
|
+
}): Promise<KoraSignResult>;
|
|
23
|
+
/** Sign and send a base64-encoded transaction via the Kora signer node */
|
|
24
|
+
signAndSendTransaction(params: {
|
|
25
|
+
transaction: string;
|
|
26
|
+
}): Promise<KoraSignResult>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Minimal Kora JSON-RPC client. Calls Kora's custom RPC methods.
|
|
30
|
+
*/
|
|
31
|
+
declare function createKoraClient(config: KoraConfig): KoraRpcClient;
|
|
32
|
+
interface KoraFacilitatorSvmSignerOptions {
|
|
33
|
+
config: KoraConfig;
|
|
34
|
+
/** Override Solana RPC URLs per network (CAIP-2 → URL) */
|
|
35
|
+
rpcUrls?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates a FacilitatorSvmSigner backed by a Kora signer node.
|
|
39
|
+
*
|
|
40
|
+
* Kora handles fee payment in USDC (or other SPL tokens) instead of SOL.
|
|
41
|
+
* The facilitator delegates transaction signing to the Kora node which:
|
|
42
|
+
* 1. Adds its fee payer as the transaction fee payer
|
|
43
|
+
* 2. Signs the transaction with its fee payer key
|
|
44
|
+
* 3. Charges the agent in USDC for gas costs
|
|
45
|
+
*
|
|
46
|
+
* IMPORTANT: Call `await signer.init()` before using — fetches the fee payer address.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createKoraFacilitatorSvmSigner(options: KoraFacilitatorSvmSignerOptions): FacilitatorSvmSigner & {
|
|
49
|
+
init(): Promise<void>;
|
|
50
|
+
};
|
|
51
|
+
export { createKoraClient, type KoraRpcClient };
|
|
52
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/kora/signer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,UAAU,qBAAqB;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,aAAa;IACrB,qFAAqF;IACrF,cAAc,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjD,gEAAgE;IAChE,eAAe,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1E,0EAA0E;IAC1E,sBAAsB,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAClF;AAED;;GAEG;AACH,iBAAS,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAoC3D;AAED,UAAU,+BAA+B;IACvC,MAAM,EAAE,UAAU,CAAC;IACnB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,oBAAoB,GAAG;IAAE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA6HlD;AAED,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { createSolanaRpc, signature } from "@solana/kit";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal Kora JSON-RPC client. Calls Kora's custom RPC methods.
|
|
4
|
+
*/
|
|
5
|
+
function createKoraClient(config) {
|
|
6
|
+
let requestId = 0;
|
|
7
|
+
async function rpcCall(method, params) {
|
|
8
|
+
const headers = { "Content-Type": "application/json" };
|
|
9
|
+
if (config.apiKey) {
|
|
10
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
11
|
+
}
|
|
12
|
+
const res = await fetch(config.rpcUrl, {
|
|
13
|
+
method: "POST",
|
|
14
|
+
headers,
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
jsonrpc: "2.0",
|
|
17
|
+
id: ++requestId,
|
|
18
|
+
method,
|
|
19
|
+
params: params ?? [],
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
if (!res.ok) {
|
|
23
|
+
throw new Error(`Kora RPC error: ${res.status} ${res.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const json = (await res.json());
|
|
26
|
+
if (json.error) {
|
|
27
|
+
throw new Error(`Kora RPC error [${json.error.code}]: ${json.error.message}`);
|
|
28
|
+
}
|
|
29
|
+
return json.result;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
getPayerSigner: () => rpcCall("getPayerSigner"),
|
|
33
|
+
signTransaction: (params) => rpcCall("signTransaction", params),
|
|
34
|
+
signAndSendTransaction: (params) => rpcCall("signAndSendTransaction", params),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates a FacilitatorSvmSigner backed by a Kora signer node.
|
|
39
|
+
*
|
|
40
|
+
* Kora handles fee payment in USDC (or other SPL tokens) instead of SOL.
|
|
41
|
+
* The facilitator delegates transaction signing to the Kora node which:
|
|
42
|
+
* 1. Adds its fee payer as the transaction fee payer
|
|
43
|
+
* 2. Signs the transaction with its fee payer key
|
|
44
|
+
* 3. Charges the agent in USDC for gas costs
|
|
45
|
+
*
|
|
46
|
+
* IMPORTANT: Call `await signer.init()` before using — fetches the fee payer address.
|
|
47
|
+
*/
|
|
48
|
+
export function createKoraFacilitatorSvmSigner(options) {
|
|
49
|
+
const { config, rpcUrls } = options;
|
|
50
|
+
const kora = createKoraClient(config);
|
|
51
|
+
// Cached fee payer address — populated during init()
|
|
52
|
+
let feePayerAddress = null;
|
|
53
|
+
// Cache Solana RPC connections for simulation/confirmation
|
|
54
|
+
const rpcCache = new Map();
|
|
55
|
+
function getSolanaRpc(network) {
|
|
56
|
+
let rpc = rpcCache.get(network);
|
|
57
|
+
if (!rpc) {
|
|
58
|
+
const url = rpcUrls?.[network] ?? "https://api.devnet.solana.com";
|
|
59
|
+
rpc = createSolanaRpc(url);
|
|
60
|
+
rpcCache.set(network, rpc);
|
|
61
|
+
}
|
|
62
|
+
return rpc;
|
|
63
|
+
}
|
|
64
|
+
const signer = {
|
|
65
|
+
/**
|
|
66
|
+
* Fetch the Kora fee payer address. Must be called before getAddresses().
|
|
67
|
+
*/
|
|
68
|
+
async init() {
|
|
69
|
+
const result = await kora.getPayerSigner();
|
|
70
|
+
feePayerAddress = result.signer_address;
|
|
71
|
+
},
|
|
72
|
+
getAddresses() {
|
|
73
|
+
if (!feePayerAddress) {
|
|
74
|
+
throw new Error("KoraFacilitatorSvmSigner not initialized — call init() first");
|
|
75
|
+
}
|
|
76
|
+
return [feePayerAddress];
|
|
77
|
+
},
|
|
78
|
+
async signTransaction(transaction, _feePayer, _network) {
|
|
79
|
+
const result = await kora.signTransaction({ transaction });
|
|
80
|
+
return result.signed_transaction;
|
|
81
|
+
},
|
|
82
|
+
async simulateTransaction(transaction, network) {
|
|
83
|
+
const rpc = getSolanaRpc(network);
|
|
84
|
+
// Simulate using the standard Solana RPC — cast transaction to expected encoded type
|
|
85
|
+
const result = await rpc
|
|
86
|
+
.simulateTransaction(transaction, {
|
|
87
|
+
commitment: "confirmed",
|
|
88
|
+
replaceRecentBlockhash: true,
|
|
89
|
+
encoding: "base64",
|
|
90
|
+
})
|
|
91
|
+
.send();
|
|
92
|
+
if (result.value.err) {
|
|
93
|
+
throw new Error(`Transaction simulation failed: ${JSON.stringify(result.value.err)}`);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
async sendTransaction(transaction, network) {
|
|
97
|
+
// Transaction is already fully signed by signTransaction() — submit directly
|
|
98
|
+
// to Solana RPC instead of Kora's signAndSendTransaction (which would re-sign).
|
|
99
|
+
// Use raw fetch to avoid @solana/kit type/encoding issues.
|
|
100
|
+
const url = rpcUrls?.[network] ?? "https://api.devnet.solana.com";
|
|
101
|
+
const res = await fetch(url, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers: { "Content-Type": "application/json" },
|
|
104
|
+
body: JSON.stringify({
|
|
105
|
+
jsonrpc: "2.0",
|
|
106
|
+
id: 1,
|
|
107
|
+
method: "sendTransaction",
|
|
108
|
+
params: [transaction, {
|
|
109
|
+
encoding: "base64",
|
|
110
|
+
skipPreflight: false,
|
|
111
|
+
preflightCommitment: "confirmed",
|
|
112
|
+
}],
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
115
|
+
const json = (await res.json());
|
|
116
|
+
if (json.error) {
|
|
117
|
+
throw new Error(`Solana sendTransaction failed [${json.error.code}]: ${json.error.message}` +
|
|
118
|
+
(json.error.data ? ` (${JSON.stringify(json.error.data)})` : ""));
|
|
119
|
+
}
|
|
120
|
+
return json.result;
|
|
121
|
+
},
|
|
122
|
+
async confirmTransaction(sig, network) {
|
|
123
|
+
const rpc = getSolanaRpc(network);
|
|
124
|
+
const brandedSig = signature(sig);
|
|
125
|
+
// Poll for confirmation with timeout
|
|
126
|
+
const timeout = 30_000;
|
|
127
|
+
const interval = 2_000;
|
|
128
|
+
const start = Date.now();
|
|
129
|
+
while (Date.now() - start < timeout) {
|
|
130
|
+
const statuses = await rpc
|
|
131
|
+
.getSignatureStatuses([brandedSig], { searchTransactionHistory: true })
|
|
132
|
+
.send();
|
|
133
|
+
const status = statuses.value[0];
|
|
134
|
+
if (status) {
|
|
135
|
+
if (status.err) {
|
|
136
|
+
throw new Error(`Transaction failed: ${JSON.stringify(status.err)}`);
|
|
137
|
+
}
|
|
138
|
+
if (status.confirmationStatus === "confirmed" ||
|
|
139
|
+
status.confirmationStatus === "finalized") {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
144
|
+
}
|
|
145
|
+
throw new Error(`Transaction confirmation timed out after ${timeout}ms`);
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
return signer;
|
|
149
|
+
}
|
|
150
|
+
export { createKoraClient };
|
|
151
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/kora/signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Address } from "@solana/kit";
|
|
2
|
+
import { SQUADS_PROGRAM_ID } from "./types.js";
|
|
3
|
+
export { SQUADS_PROGRAM_ID };
|
|
4
|
+
/**
|
|
5
|
+
* Derive the Smart Account PDA.
|
|
6
|
+
* Seeds: ["smart_account", creator, account_index (u32 LE)]
|
|
7
|
+
*/
|
|
8
|
+
export declare function deriveSmartAccountPda(creator: Address, accountIndex: number, programId?: Address): Promise<readonly [Address, number]>;
|
|
9
|
+
/**
|
|
10
|
+
* Derive the Settings PDA for a Smart Account.
|
|
11
|
+
* Seeds: ["settings", smart_account_pda]
|
|
12
|
+
*/
|
|
13
|
+
export declare function deriveSettingsPda(smartAccountPda: Address, programId?: Address): Promise<readonly [Address, number]>;
|
|
14
|
+
/**
|
|
15
|
+
* Derive a Spending Limit PDA.
|
|
16
|
+
* Seeds: ["spending_limit", smart_account_pda, spending_limit_index (u32 LE)]
|
|
17
|
+
*/
|
|
18
|
+
export declare function deriveSpendingLimitPda(smartAccountPda: Address, spendingLimitIndex: number, programId?: Address): Promise<readonly [Address, number]>;
|
|
19
|
+
//# sourceMappingURL=accounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/squads/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,OAA2B,GACrC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAarC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,OAAO,EACxB,SAAS,GAAE,OAA2B,GACrC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CASrC;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,OAAO,EACxB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,GAAE,OAA2B,GACrC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAarC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getAddressEncoder, getProgramDerivedAddress } from "@solana/kit";
|
|
2
|
+
import { SQUADS_PROGRAM_ID } from "./types.js";
|
|
3
|
+
export { SQUADS_PROGRAM_ID };
|
|
4
|
+
/**
|
|
5
|
+
* Derive the Smart Account PDA.
|
|
6
|
+
* Seeds: ["smart_account", creator, account_index (u32 LE)]
|
|
7
|
+
*/
|
|
8
|
+
export async function deriveSmartAccountPda(creator, accountIndex, programId = SQUADS_PROGRAM_ID) {
|
|
9
|
+
const encoder = getAddressEncoder();
|
|
10
|
+
const indexBuffer = new Uint8Array(4);
|
|
11
|
+
new DataView(indexBuffer.buffer).setUint32(0, accountIndex, true); // little-endian
|
|
12
|
+
return getProgramDerivedAddress({
|
|
13
|
+
programAddress: programId,
|
|
14
|
+
seeds: [
|
|
15
|
+
new TextEncoder().encode("smart_account"),
|
|
16
|
+
encoder.encode(creator),
|
|
17
|
+
indexBuffer,
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Derive the Settings PDA for a Smart Account.
|
|
23
|
+
* Seeds: ["settings", smart_account_pda]
|
|
24
|
+
*/
|
|
25
|
+
export async function deriveSettingsPda(smartAccountPda, programId = SQUADS_PROGRAM_ID) {
|
|
26
|
+
const encoder = getAddressEncoder();
|
|
27
|
+
return getProgramDerivedAddress({
|
|
28
|
+
programAddress: programId,
|
|
29
|
+
seeds: [
|
|
30
|
+
new TextEncoder().encode("settings"),
|
|
31
|
+
encoder.encode(smartAccountPda),
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Derive a Spending Limit PDA.
|
|
37
|
+
* Seeds: ["spending_limit", smart_account_pda, spending_limit_index (u32 LE)]
|
|
38
|
+
*/
|
|
39
|
+
export async function deriveSpendingLimitPda(smartAccountPda, spendingLimitIndex, programId = SQUADS_PROGRAM_ID) {
|
|
40
|
+
const encoder = getAddressEncoder();
|
|
41
|
+
const indexBuffer = new Uint8Array(4);
|
|
42
|
+
new DataView(indexBuffer.buffer).setUint32(0, spendingLimitIndex, true);
|
|
43
|
+
return getProgramDerivedAddress({
|
|
44
|
+
programAddress: programId,
|
|
45
|
+
seeds: [
|
|
46
|
+
new TextEncoder().encode("spending_limit"),
|
|
47
|
+
encoder.encode(smartAccountPda),
|
|
48
|
+
indexBuffer,
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/squads/accounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAgB,EAChB,YAAoB,EACpB,YAAqB,iBAAiB;IAEtC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,gBAAgB;IAEnF,OAAO,wBAAwB,CAAC;QAC9B,cAAc,EAAE,SAAS;QACzB,KAAK,EAAE;YACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC;YACzC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;YACvB,WAAW;SACZ;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAwB,EACxB,YAAqB,iBAAiB;IAEtC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,OAAO,wBAAwB,CAAC;QAC9B,cAAc,EAAE,SAAS;QACzB,KAAK,EAAE;YACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC;SAChC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,eAAwB,EACxB,kBAA0B,EAC1B,YAAqB,iBAAiB;IAEtC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAExE,OAAO,wBAAwB,CAAC;QAC9B,cAAc,EAAE,SAAS;QACzB,KAAK,EAAE;YACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC;YAC/B,WAAW;SACZ;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { deriveSmartAccountPda, deriveSettingsPda, deriveSpendingLimitPda, SQUADS_PROGRAM_ID } from "./accounts.js";
|
|
2
|
+
export { createSmartAccountInstruction, addSpendingLimitInstruction, useSpendingLimitInstruction, removeSpendingLimitInstruction } from "./instructions.js";
|
|
3
|
+
export { createSpendingLimit, checkSpendingLimit, revokeSpendingLimit } from "./spending.js";
|
|
4
|
+
export { SpendingLimitPeriod } from "./types.js";
|
|
5
|
+
export type { SpendingLimitConfig, SmartAccountConfig } from "./types.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/squads/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAC5J,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Squads Smart Account module — implemented in task S2b
|
|
2
|
+
export { deriveSmartAccountPda, deriveSettingsPda, deriveSpendingLimitPda, SQUADS_PROGRAM_ID } from "./accounts.js";
|
|
3
|
+
export { createSmartAccountInstruction, addSpendingLimitInstruction, useSpendingLimitInstruction, removeSpendingLimitInstruction } from "./instructions.js";
|
|
4
|
+
export { createSpendingLimit, checkSpendingLimit, revokeSpendingLimit } from "./spending.js";
|
|
5
|
+
export { SpendingLimitPeriod } from "./types.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/squads/index.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAC5J,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Address, Instruction } from "@solana/kit";
|
|
2
|
+
import { type SmartAccountConfig, type SpendingLimitConfig, SpendingLimitPeriod } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a `createSmartAccount` instruction.
|
|
5
|
+
* Initializes a new Squads Smart Account with the given signers and threshold.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createSmartAccountInstruction(config: SmartAccountConfig): Promise<Instruction>;
|
|
8
|
+
/**
|
|
9
|
+
* Build an `addSpendingLimitAsAuthority` instruction.
|
|
10
|
+
* Sets a per-mint spending cap with time period on a Smart Account.
|
|
11
|
+
*/
|
|
12
|
+
export declare function addSpendingLimitInstruction(config: SpendingLimitConfig, spendingLimitIndex: number, authority: Address): Promise<Instruction>;
|
|
13
|
+
/**
|
|
14
|
+
* Build a `useSpendingLimit` instruction.
|
|
15
|
+
* Spends within the limit — no proposal required.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useSpendingLimitInstruction(params: {
|
|
18
|
+
smartAccountPda: Address;
|
|
19
|
+
spendingLimitIndex: number;
|
|
20
|
+
/** Token mint (USDC) */
|
|
21
|
+
mint: Address;
|
|
22
|
+
/** Source token account (Smart Account's ATA) */
|
|
23
|
+
sourceTokenAccount: Address;
|
|
24
|
+
/** Destination token account */
|
|
25
|
+
destinationTokenAccount: Address;
|
|
26
|
+
/** Member (agent) signing the transaction */
|
|
27
|
+
member: Address;
|
|
28
|
+
/** Amount to spend (base units) */
|
|
29
|
+
amount: bigint;
|
|
30
|
+
}): Promise<Instruction>;
|
|
31
|
+
/**
|
|
32
|
+
* Build a `removeSpendingLimitAsAuthority` instruction.
|
|
33
|
+
* Revokes a spending limit from the Smart Account.
|
|
34
|
+
*/
|
|
35
|
+
export declare function removeSpendingLimitInstruction(params: {
|
|
36
|
+
smartAccountPda: Address;
|
|
37
|
+
spendingLimitIndex: number;
|
|
38
|
+
authority: Address;
|
|
39
|
+
/** Account to receive the rent-exempt lamports */
|
|
40
|
+
rentCollector: Address;
|
|
41
|
+
}): Promise<Instruction>;
|
|
42
|
+
export { SpendingLimitPeriod };
|
|
43
|
+
//# sourceMappingURL=instructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/squads/instructions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAqB,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA+BvH;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,WAAW,CAAC,CAqCtB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,WAAW,CAAC,CAqDtB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE;IACxD,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,iDAAiD;IACjD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gCAAgC;IAChC,uBAAuB,EAAE,OAAO,CAAC;IACjC,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwBvB;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,MAAM,EAAE;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBvB;AAGD,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { getAddressEncoder } from "@solana/kit";
|
|
2
|
+
import { SQUADS_PROGRAM_ID, SpendingLimitPeriod } from "./types.js";
|
|
3
|
+
import { deriveSmartAccountPda, deriveSettingsPda, deriveSpendingLimitPda } from "./accounts.js";
|
|
4
|
+
// Anchor discriminators are first 8 bytes of sha256("global:<instruction_name>")
|
|
5
|
+
// Pre-computed for the 4 instructions we need
|
|
6
|
+
/** sha256("global:create_smart_account")[0..8] */
|
|
7
|
+
const CREATE_SMART_ACCOUNT_DISC = new Uint8Array([
|
|
8
|
+
0x18, 0x46, 0xf0, 0x52, 0x88, 0xa5, 0x03, 0x26,
|
|
9
|
+
]);
|
|
10
|
+
/** sha256("global:add_spending_limit_as_authority")[0..8] */
|
|
11
|
+
const ADD_SPENDING_LIMIT_DISC = new Uint8Array([
|
|
12
|
+
0xd1, 0x81, 0xb2, 0x0f, 0x07, 0x0c, 0x79, 0xa2,
|
|
13
|
+
]);
|
|
14
|
+
/** sha256("global:use_spending_limit")[0..8] */
|
|
15
|
+
const USE_SPENDING_LIMIT_DISC = new Uint8Array([
|
|
16
|
+
0x65, 0x7b, 0x5a, 0xf7, 0x80, 0x5e, 0x89, 0x11,
|
|
17
|
+
]);
|
|
18
|
+
/** sha256("global:remove_spending_limit_as_authority")[0..8] */
|
|
19
|
+
const REMOVE_SPENDING_LIMIT_DISC = new Uint8Array([
|
|
20
|
+
0xc9, 0x18, 0x27, 0x0d, 0x3e, 0x5b, 0x7a, 0x4f,
|
|
21
|
+
]);
|
|
22
|
+
/** System Program ID */
|
|
23
|
+
const SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
24
|
+
/** SPL Token Program ID */
|
|
25
|
+
const TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
26
|
+
/**
|
|
27
|
+
* Build a `createSmartAccount` instruction.
|
|
28
|
+
* Initializes a new Squads Smart Account with the given signers and threshold.
|
|
29
|
+
*/
|
|
30
|
+
export async function createSmartAccountInstruction(config) {
|
|
31
|
+
const [smartAccountPda] = await deriveSmartAccountPda(config.creator, config.accountIndex);
|
|
32
|
+
const [settingsPda] = await deriveSettingsPda(smartAccountPda);
|
|
33
|
+
// Serialize args: threshold (u16 LE) + members count (u32 LE) + members (32 bytes each)
|
|
34
|
+
const argsSize = 8 + 2 + 4 + config.members.length * 32;
|
|
35
|
+
const data = new Uint8Array(argsSize);
|
|
36
|
+
const view = new DataView(data.buffer);
|
|
37
|
+
let offset = 0;
|
|
38
|
+
// Discriminator
|
|
39
|
+
data.set(CREATE_SMART_ACCOUNT_DISC, offset);
|
|
40
|
+
offset += 8;
|
|
41
|
+
// Threshold (u16 LE)
|
|
42
|
+
view.setUint16(offset, config.threshold, true);
|
|
43
|
+
offset += 2;
|
|
44
|
+
// Members array (Borsh: u32 length prefix + items)
|
|
45
|
+
const encoder = getAddressEncoder();
|
|
46
|
+
view.setUint32(offset, config.members.length, true);
|
|
47
|
+
offset += 4;
|
|
48
|
+
for (const member of config.members) {
|
|
49
|
+
data.set(encoder.encode(member), offset);
|
|
50
|
+
offset += 32;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
programAddress: SQUADS_PROGRAM_ID,
|
|
54
|
+
accounts: [
|
|
55
|
+
{ address: smartAccountPda, role: 1 }, // writable
|
|
56
|
+
{ address: settingsPda, role: 1 }, // writable
|
|
57
|
+
{ address: config.creator, role: 3 }, // writable + signer
|
|
58
|
+
{ address: SYSTEM_PROGRAM, role: 0 }, // readonly
|
|
59
|
+
],
|
|
60
|
+
data,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build an `addSpendingLimitAsAuthority` instruction.
|
|
65
|
+
* Sets a per-mint spending cap with time period on a Smart Account.
|
|
66
|
+
*/
|
|
67
|
+
export async function addSpendingLimitInstruction(config, spendingLimitIndex, authority) {
|
|
68
|
+
const [settingsPda] = await deriveSettingsPda(config.smartAccountPda);
|
|
69
|
+
const [spendingLimitPda] = await deriveSpendingLimitPda(config.smartAccountPda, spendingLimitIndex);
|
|
70
|
+
// Serialize: disc + mint(32) + amount(u64 LE) + period(u8) + members_len(u32) + members + destinations_len(u32) + destinations
|
|
71
|
+
const argsSize = 8 + 32 + 8 + 1 + 4 + config.members.length * 32 + 4 + config.destinations.length * 32;
|
|
72
|
+
const data = new Uint8Array(argsSize);
|
|
73
|
+
const view = new DataView(data.buffer);
|
|
74
|
+
const encoder = getAddressEncoder();
|
|
75
|
+
let offset = 0;
|
|
76
|
+
data.set(ADD_SPENDING_LIMIT_DISC, offset);
|
|
77
|
+
offset += 8;
|
|
78
|
+
// Mint
|
|
79
|
+
data.set(encoder.encode(config.mint), offset);
|
|
80
|
+
offset += 32;
|
|
81
|
+
// Amount (u64 LE)
|
|
82
|
+
view.setBigUint64(offset, config.amount, true);
|
|
83
|
+
offset += 8;
|
|
84
|
+
// Period (u8 enum)
|
|
85
|
+
data[offset] = config.period;
|
|
86
|
+
offset += 1;
|
|
87
|
+
// Members
|
|
88
|
+
view.setUint32(offset, config.members.length, true);
|
|
89
|
+
offset += 4;
|
|
90
|
+
for (const member of config.members) {
|
|
91
|
+
data.set(encoder.encode(member), offset);
|
|
92
|
+
offset += 32;
|
|
93
|
+
}
|
|
94
|
+
// Destinations
|
|
95
|
+
view.setUint32(offset, config.destinations.length, true);
|
|
96
|
+
offset += 4;
|
|
97
|
+
for (const dest of config.destinations) {
|
|
98
|
+
data.set(encoder.encode(dest), offset);
|
|
99
|
+
offset += 32;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
programAddress: SQUADS_PROGRAM_ID,
|
|
103
|
+
accounts: [
|
|
104
|
+
{ address: config.smartAccountPda, role: 0 }, // readonly
|
|
105
|
+
{ address: settingsPda, role: 0 }, // readonly
|
|
106
|
+
{ address: spendingLimitPda, role: 1 }, // writable
|
|
107
|
+
{ address: authority, role: 3 }, // writable + signer
|
|
108
|
+
{ address: SYSTEM_PROGRAM, role: 0 }, // readonly
|
|
109
|
+
],
|
|
110
|
+
data,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Build a `useSpendingLimit` instruction.
|
|
115
|
+
* Spends within the limit — no proposal required.
|
|
116
|
+
*/
|
|
117
|
+
export async function useSpendingLimitInstruction(params) {
|
|
118
|
+
const [settingsPda] = await deriveSettingsPda(params.smartAccountPda);
|
|
119
|
+
const [spendingLimitPda] = await deriveSpendingLimitPda(params.smartAccountPda, params.spendingLimitIndex);
|
|
120
|
+
// Serialize: disc + amount(u64 LE)
|
|
121
|
+
const data = new Uint8Array(8 + 8);
|
|
122
|
+
const view = new DataView(data.buffer);
|
|
123
|
+
data.set(USE_SPENDING_LIMIT_DISC, 0);
|
|
124
|
+
view.setBigUint64(8, params.amount, true);
|
|
125
|
+
return {
|
|
126
|
+
programAddress: SQUADS_PROGRAM_ID,
|
|
127
|
+
accounts: [
|
|
128
|
+
{ address: params.smartAccountPda, role: 0 }, // readonly
|
|
129
|
+
{ address: settingsPda, role: 0 }, // readonly
|
|
130
|
+
{ address: spendingLimitPda, role: 1 }, // writable
|
|
131
|
+
{ address: params.sourceTokenAccount, role: 1 }, // writable
|
|
132
|
+
{ address: params.destinationTokenAccount, role: 1 }, // writable
|
|
133
|
+
{ address: params.member, role: 2 }, // signer
|
|
134
|
+
{ address: params.mint, role: 0 }, // readonly
|
|
135
|
+
{ address: TOKEN_PROGRAM, role: 0 }, // readonly
|
|
136
|
+
],
|
|
137
|
+
data,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build a `removeSpendingLimitAsAuthority` instruction.
|
|
142
|
+
* Revokes a spending limit from the Smart Account.
|
|
143
|
+
*/
|
|
144
|
+
export async function removeSpendingLimitInstruction(params) {
|
|
145
|
+
const [settingsPda] = await deriveSettingsPda(params.smartAccountPda);
|
|
146
|
+
const [spendingLimitPda] = await deriveSpendingLimitPda(params.smartAccountPda, params.spendingLimitIndex);
|
|
147
|
+
const data = new Uint8Array(8);
|
|
148
|
+
data.set(REMOVE_SPENDING_LIMIT_DISC, 0);
|
|
149
|
+
return {
|
|
150
|
+
programAddress: SQUADS_PROGRAM_ID,
|
|
151
|
+
accounts: [
|
|
152
|
+
{ address: params.smartAccountPda, role: 0 }, // readonly
|
|
153
|
+
{ address: settingsPda, role: 0 }, // readonly
|
|
154
|
+
{ address: spendingLimitPda, role: 1 }, // writable (closed)
|
|
155
|
+
{ address: params.authority, role: 3 }, // writable + signer
|
|
156
|
+
{ address: params.rentCollector, role: 1 }, // writable (receives lamports)
|
|
157
|
+
],
|
|
158
|
+
data,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Re-export for convenience
|
|
162
|
+
export { SpendingLimitPeriod };
|
|
163
|
+
//# sourceMappingURL=instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/squads/instructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Address } from "@solana/kit";
|
|
2
|
+
import type { SpendingLimitConfig } from "./types.js";
|
|
3
|
+
import { SpendingLimitPeriod } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Create a spending limit instruction for a Smart Account.
|
|
6
|
+
* Returns the instruction — caller is responsible for signing and sending.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createSpendingLimit(config: SpendingLimitConfig, spendingLimitIndex: number, authority: Address): Promise<import("@solana/kit").Instruction<string, readonly (import("@solana/kit").AccountLookupMeta<string, string> | import("@solana/kit").AccountMeta<string>)[]>>;
|
|
9
|
+
/**
|
|
10
|
+
* Check if a spending limit account exists on-chain and fetch its state.
|
|
11
|
+
* Returns null if the account doesn't exist.
|
|
12
|
+
*/
|
|
13
|
+
export declare function checkSpendingLimit(smartAccountPda: Address, spendingLimitIndex: number, rpcUrl: string): Promise<{
|
|
14
|
+
exists: boolean;
|
|
15
|
+
remainingAmount?: bigint;
|
|
16
|
+
period?: SpendingLimitPeriod;
|
|
17
|
+
lastReset?: bigint;
|
|
18
|
+
} | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Revoke a spending limit from a Smart Account.
|
|
21
|
+
* Returns the instruction — caller is responsible for signing and sending.
|
|
22
|
+
*/
|
|
23
|
+
export declare function revokeSpendingLimit(smartAccountPda: Address, spendingLimitIndex: number, authority: Address, rentCollector: Address): Promise<import("@solana/kit").Instruction<string, readonly (import("@solana/kit").AccountLookupMeta<string, string> | import("@solana/kit").AccountMeta<string>)[]>>;
|
|
24
|
+
//# sourceMappingURL=spending.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spending.d.ts","sourceRoot":"","sources":["../../src/squads/spending.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIjD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,OAAO,wKAGnB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,eAAe,EAAE,OAAO,EACxB,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAAC,CA8BR;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,OAAO,EACxB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,OAAO,wKAQvB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createSolanaRpc } from "@solana/kit";
|
|
2
|
+
import { SpendingLimitPeriod } from "./types.js";
|
|
3
|
+
import { deriveSpendingLimitPda } from "./accounts.js";
|
|
4
|
+
import { addSpendingLimitInstruction, removeSpendingLimitInstruction } from "./instructions.js";
|
|
5
|
+
/**
|
|
6
|
+
* Create a spending limit instruction for a Smart Account.
|
|
7
|
+
* Returns the instruction — caller is responsible for signing and sending.
|
|
8
|
+
*/
|
|
9
|
+
export async function createSpendingLimit(config, spendingLimitIndex, authority) {
|
|
10
|
+
return addSpendingLimitInstruction(config, spendingLimitIndex, authority);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if a spending limit account exists on-chain and fetch its state.
|
|
14
|
+
* Returns null if the account doesn't exist.
|
|
15
|
+
*/
|
|
16
|
+
export async function checkSpendingLimit(smartAccountPda, spendingLimitIndex, rpcUrl) {
|
|
17
|
+
const rpc = createSolanaRpc(rpcUrl);
|
|
18
|
+
const [spendingLimitPda] = await deriveSpendingLimitPda(smartAccountPda, spendingLimitIndex);
|
|
19
|
+
const accountInfo = await rpc
|
|
20
|
+
.getAccountInfo(spendingLimitPda, { encoding: "base64" })
|
|
21
|
+
.send();
|
|
22
|
+
if (!accountInfo.value) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
// Parse the account data
|
|
26
|
+
// Layout: discriminator(8) + smart_account(32) + mint(32) + amount(8) + remaining_amount(8) + period(1) + last_reset(8) + ...
|
|
27
|
+
const data = Buffer.from(accountInfo.value.data[0], "base64");
|
|
28
|
+
if (data.length < 89) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
32
|
+
const remainingAmount = view.getBigUint64(80, true); // offset 8+32+32+8 = 80
|
|
33
|
+
const period = data[88]; // offset 80+8 = 88
|
|
34
|
+
const lastReset = view.getBigUint64(89, true); // offset 88+1 = 89
|
|
35
|
+
return {
|
|
36
|
+
exists: true,
|
|
37
|
+
remainingAmount,
|
|
38
|
+
period,
|
|
39
|
+
lastReset,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Revoke a spending limit from a Smart Account.
|
|
44
|
+
* Returns the instruction — caller is responsible for signing and sending.
|
|
45
|
+
*/
|
|
46
|
+
export async function revokeSpendingLimit(smartAccountPda, spendingLimitIndex, authority, rentCollector) {
|
|
47
|
+
return removeSpendingLimitInstruction({
|
|
48
|
+
smartAccountPda,
|
|
49
|
+
spendingLimitIndex,
|
|
50
|
+
authority,
|
|
51
|
+
rentCollector,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=spending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spending.js","sourceRoot":"","sources":["../../src/squads/spending.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAEhG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAA2B,EAC3B,kBAA0B,EAC1B,SAAkB;IAElB,OAAO,2BAA2B,CAAC,MAAM,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,eAAwB,EACxB,kBAA0B,EAC1B,MAAc;IAOd,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,gBAAgB,CAAC,GAAG,MAAM,sBAAsB,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAE7F,MAAM,WAAW,GAAG,MAAM,GAAG;SAC1B,cAAc,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;SACxD,IAAI,EAAE,CAAC;IAEV,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yBAAyB;IACzB,8HAA8H;IAC9H,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,QAAQ,CAAC,CAAC;IACxE,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACzE,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,wBAAwB;IAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAwB,CAAC,CAAC,mBAAmB;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,mBAAmB;IAElE,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,eAAe;QACf,MAAM;QACN,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,eAAwB,EACxB,kBAA0B,EAC1B,SAAkB,EAClB,aAAsB;IAEtB,OAAO,8BAA8B,CAAC;QACpC,eAAe;QACf,kBAAkB;QAClB,SAAS;QACT,aAAa;KACd,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Address } from "@solana/kit";
|
|
2
|
+
/** Squads Smart Account program ID on mainnet/devnet */
|
|
3
|
+
export declare const SQUADS_PROGRAM_ID: Address;
|
|
4
|
+
/** Configuration for creating a spending limit on a Smart Account */
|
|
5
|
+
export interface SpendingLimitConfig {
|
|
6
|
+
/** The Smart Account PDA that owns this spending limit */
|
|
7
|
+
smartAccountPda: Address;
|
|
8
|
+
/** Token mint address (USDC) */
|
|
9
|
+
mint: Address;
|
|
10
|
+
/** Maximum amount allowed per time period (base units) */
|
|
11
|
+
amount: bigint;
|
|
12
|
+
/** Time period for the spending limit */
|
|
13
|
+
period: SpendingLimitPeriod;
|
|
14
|
+
/** Members (agent addresses) authorized to use this spending limit */
|
|
15
|
+
members: Address[];
|
|
16
|
+
/** Destination addresses the agent can send to */
|
|
17
|
+
destinations: Address[];
|
|
18
|
+
}
|
|
19
|
+
/** Time period for spending limit reset */
|
|
20
|
+
export declare enum SpendingLimitPeriod {
|
|
21
|
+
/** One-time allowance — no reset */
|
|
22
|
+
OneTime = 0,
|
|
23
|
+
/** Resets daily */
|
|
24
|
+
Day = 1,
|
|
25
|
+
/** Resets weekly */
|
|
26
|
+
Week = 2,
|
|
27
|
+
/** Resets monthly */
|
|
28
|
+
Month = 3
|
|
29
|
+
}
|
|
30
|
+
/** Configuration for creating a Smart Account */
|
|
31
|
+
export interface SmartAccountConfig {
|
|
32
|
+
/** Creator/authority address */
|
|
33
|
+
creator: Address;
|
|
34
|
+
/** Index for PDA derivation (allows multiple accounts per creator) */
|
|
35
|
+
accountIndex: number;
|
|
36
|
+
/** Signers for the multisig */
|
|
37
|
+
members: Address[];
|
|
38
|
+
/** Number of required signers */
|
|
39
|
+
threshold: number;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/squads/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAoD,OAAO,CAAC;AAE1F,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,eAAe,EAAE,OAAO,CAAC;IACzB,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,sEAAsE;IACtE,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,kDAAkD;IAClD,YAAY,EAAE,OAAO,EAAE,CAAC;CACzB;AAED,2CAA2C;AAC3C,oBAAY,mBAAmB;IAC7B,oCAAoC;IACpC,OAAO,IAAI;IACX,mBAAmB;IACnB,GAAG,IAAI;IACP,oBAAoB;IACpB,IAAI,IAAI;IACR,qBAAqB;IACrB,KAAK,IAAI;CACV;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Squads Smart Account program ID on mainnet/devnet */
|
|
2
|
+
export const SQUADS_PROGRAM_ID = "SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG";
|
|
3
|
+
/** Time period for spending limit reset */
|
|
4
|
+
export var SpendingLimitPeriod;
|
|
5
|
+
(function (SpendingLimitPeriod) {
|
|
6
|
+
/** One-time allowance — no reset */
|
|
7
|
+
SpendingLimitPeriod[SpendingLimitPeriod["OneTime"] = 0] = "OneTime";
|
|
8
|
+
/** Resets daily */
|
|
9
|
+
SpendingLimitPeriod[SpendingLimitPeriod["Day"] = 1] = "Day";
|
|
10
|
+
/** Resets weekly */
|
|
11
|
+
SpendingLimitPeriod[SpendingLimitPeriod["Week"] = 2] = "Week";
|
|
12
|
+
/** Resets monthly */
|
|
13
|
+
SpendingLimitPeriod[SpendingLimitPeriod["Month"] = 3] = "Month";
|
|
14
|
+
})(SpendingLimitPeriod || (SpendingLimitPeriod = {}));
|
|
15
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/squads/types.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,6CAAwD,CAAC;AAkB1F,2CAA2C;AAC3C,MAAM,CAAN,IAAY,mBASX;AATD,WAAY,mBAAmB;IAC7B,oCAAoC;IACpC,mEAAW,CAAA;IACX,mBAAmB;IACnB,2DAAO,CAAA;IACP,oBAAoB;IACpB,6DAAQ,CAAA;IACR,qBAAqB;IACrB,+DAAS,CAAA;AACX,CAAC,EATW,mBAAmB,KAAnB,mBAAmB,QAS9B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pincerpay/solana",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Solana integration for PincerPay. Kora gasless transactions and Squads smart account support.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://pincerpay.com",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/ds1/pincerpay.git",
|
|
11
|
+
"directory": "packages/solana"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/ds1/pincerpay/issues"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"pincerpay",
|
|
21
|
+
"solana",
|
|
22
|
+
"kora",
|
|
23
|
+
"squads",
|
|
24
|
+
"gasless",
|
|
25
|
+
"usdc",
|
|
26
|
+
"smart-accounts",
|
|
27
|
+
"session-keys"
|
|
28
|
+
],
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md",
|
|
32
|
+
"LICENSE"
|
|
33
|
+
],
|
|
34
|
+
"main": "dist/index.js",
|
|
35
|
+
"types": "dist/index.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"import": "./dist/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./kora": {
|
|
42
|
+
"types": "./dist/kora/index.d.ts",
|
|
43
|
+
"import": "./dist/kora/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./squads": {
|
|
46
|
+
"types": "./dist/squads/index.d.ts",
|
|
47
|
+
"import": "./dist/squads/index.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@solana/kit": "^5.5.1",
|
|
52
|
+
"@x402/svm": "^2.3.0",
|
|
53
|
+
"zod": "^3.24",
|
|
54
|
+
"@pincerpay/core": "0.1.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@scure/base": "^1.2.6",
|
|
58
|
+
"typescript": "^5.7"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsc",
|
|
62
|
+
"test": "vitest run",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"clean": "rm -rf dist"
|
|
65
|
+
}
|
|
66
|
+
}
|