@agent-fuel/sdk 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/idl/credit-vault.cjs +475 -1
- package/dist/idl/credit-vault.cjs.map +1 -1
- package/dist/idl/credit-vault.d.cts +477 -1
- package/dist/idl/credit-vault.d.ts +477 -1
- package/dist/idl/credit-vault.js +475 -1
- package/dist/idl/credit-vault.js.map +1 -1
- package/dist/index.cjs +723 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -1
- package/dist/index.d.ts +87 -1
- package/dist/index.js +722 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BN, AnchorError,
|
|
2
|
-
import { PublicKey, TransactionInstruction, SystemProgram, Connection } from '@solana/web3.js';
|
|
1
|
+
import { BN, AnchorError, AnchorProvider, Wallet, Program } from '@coral-xyz/anchor';
|
|
2
|
+
import { PublicKey, TransactionInstruction, SystemProgram, Transaction, sendAndConfirmTransaction, Connection } from '@solana/web3.js';
|
|
3
3
|
|
|
4
4
|
// src/client.ts
|
|
5
5
|
var TOKEN_PROGRAM_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
|
@@ -61,7 +61,8 @@ function decodeCreditVault(pubkey, raw) {
|
|
|
61
61
|
balance: total_deposited - total_withdrawn - total_spent + total_claimed,
|
|
62
62
|
frozen: raw.frozen,
|
|
63
63
|
created_slot: bnToNum(raw.createdSlot),
|
|
64
|
-
last_active_slot: bnToNum(raw.lastActiveSlot)
|
|
64
|
+
last_active_slot: bnToNum(raw.lastActiveSlot),
|
|
65
|
+
pending_count: bnToNum(raw.pendingCount)
|
|
65
66
|
};
|
|
66
67
|
}
|
|
67
68
|
var DEFAULT_PUBKEY = PublicKey.default.toBase58();
|
|
@@ -1951,6 +1952,200 @@ var credit_vault_default = {
|
|
|
1951
1952
|
repository: "https://github.com/TODO/agent_fuel"
|
|
1952
1953
|
},
|
|
1953
1954
|
instructions: [
|
|
1955
|
+
{
|
|
1956
|
+
name: "approve_spend",
|
|
1957
|
+
discriminator: [
|
|
1958
|
+
248,
|
|
1959
|
+
201,
|
|
1960
|
+
151,
|
|
1961
|
+
15,
|
|
1962
|
+
28,
|
|
1963
|
+
162,
|
|
1964
|
+
112,
|
|
1965
|
+
90
|
|
1966
|
+
],
|
|
1967
|
+
accounts: [
|
|
1968
|
+
{
|
|
1969
|
+
name: "owner",
|
|
1970
|
+
writable: true,
|
|
1971
|
+
signer: true,
|
|
1972
|
+
relations: [
|
|
1973
|
+
"vault"
|
|
1974
|
+
]
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
name: "vault",
|
|
1978
|
+
writable: true,
|
|
1979
|
+
pda: {
|
|
1980
|
+
seeds: [
|
|
1981
|
+
{
|
|
1982
|
+
kind: "const",
|
|
1983
|
+
value: [
|
|
1984
|
+
118,
|
|
1985
|
+
97,
|
|
1986
|
+
117,
|
|
1987
|
+
108,
|
|
1988
|
+
116
|
|
1989
|
+
]
|
|
1990
|
+
},
|
|
1991
|
+
{
|
|
1992
|
+
kind: "account",
|
|
1993
|
+
path: "owner"
|
|
1994
|
+
},
|
|
1995
|
+
{
|
|
1996
|
+
kind: "account",
|
|
1997
|
+
path: "vault.agent",
|
|
1998
|
+
account: "CreditVault"
|
|
1999
|
+
}
|
|
2000
|
+
]
|
|
2001
|
+
}
|
|
2002
|
+
},
|
|
2003
|
+
{
|
|
2004
|
+
name: "policy",
|
|
2005
|
+
writable: true,
|
|
2006
|
+
pda: {
|
|
2007
|
+
seeds: [
|
|
2008
|
+
{
|
|
2009
|
+
kind: "const",
|
|
2010
|
+
value: [
|
|
2011
|
+
112,
|
|
2012
|
+
111,
|
|
2013
|
+
108,
|
|
2014
|
+
105,
|
|
2015
|
+
99,
|
|
2016
|
+
121
|
|
2017
|
+
]
|
|
2018
|
+
},
|
|
2019
|
+
{
|
|
2020
|
+
kind: "account",
|
|
2021
|
+
path: "vault"
|
|
2022
|
+
}
|
|
2023
|
+
]
|
|
2024
|
+
}
|
|
2025
|
+
},
|
|
2026
|
+
{
|
|
2027
|
+
name: "pending_spend",
|
|
2028
|
+
writable: true,
|
|
2029
|
+
pda: {
|
|
2030
|
+
seeds: [
|
|
2031
|
+
{
|
|
2032
|
+
kind: "const",
|
|
2033
|
+
value: [
|
|
2034
|
+
112,
|
|
2035
|
+
101,
|
|
2036
|
+
110,
|
|
2037
|
+
100,
|
|
2038
|
+
105,
|
|
2039
|
+
110,
|
|
2040
|
+
103
|
|
2041
|
+
]
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
kind: "account",
|
|
2045
|
+
path: "vault"
|
|
2046
|
+
},
|
|
2047
|
+
{
|
|
2048
|
+
kind: "account",
|
|
2049
|
+
path: "pending_spend.nonce",
|
|
2050
|
+
account: "PendingSpend"
|
|
2051
|
+
}
|
|
2052
|
+
]
|
|
2053
|
+
}
|
|
2054
|
+
},
|
|
2055
|
+
{
|
|
2056
|
+
name: "vault_token_account",
|
|
2057
|
+
writable: true
|
|
2058
|
+
},
|
|
2059
|
+
{
|
|
2060
|
+
name: "service_token_account",
|
|
2061
|
+
writable: true
|
|
2062
|
+
},
|
|
2063
|
+
{
|
|
2064
|
+
name: "token_program",
|
|
2065
|
+
address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
|
2066
|
+
}
|
|
2067
|
+
],
|
|
2068
|
+
args: []
|
|
2069
|
+
},
|
|
2070
|
+
{
|
|
2071
|
+
name: "cancel_spend",
|
|
2072
|
+
discriminator: [
|
|
2073
|
+
122,
|
|
2074
|
+
254,
|
|
2075
|
+
101,
|
|
2076
|
+
132,
|
|
2077
|
+
241,
|
|
2078
|
+
232,
|
|
2079
|
+
205,
|
|
2080
|
+
179
|
|
2081
|
+
],
|
|
2082
|
+
accounts: [
|
|
2083
|
+
{
|
|
2084
|
+
name: "owner",
|
|
2085
|
+
writable: true,
|
|
2086
|
+
signer: true,
|
|
2087
|
+
relations: [
|
|
2088
|
+
"vault"
|
|
2089
|
+
]
|
|
2090
|
+
},
|
|
2091
|
+
{
|
|
2092
|
+
name: "vault",
|
|
2093
|
+
pda: {
|
|
2094
|
+
seeds: [
|
|
2095
|
+
{
|
|
2096
|
+
kind: "const",
|
|
2097
|
+
value: [
|
|
2098
|
+
118,
|
|
2099
|
+
97,
|
|
2100
|
+
117,
|
|
2101
|
+
108,
|
|
2102
|
+
116
|
|
2103
|
+
]
|
|
2104
|
+
},
|
|
2105
|
+
{
|
|
2106
|
+
kind: "account",
|
|
2107
|
+
path: "owner"
|
|
2108
|
+
},
|
|
2109
|
+
{
|
|
2110
|
+
kind: "account",
|
|
2111
|
+
path: "vault.agent",
|
|
2112
|
+
account: "CreditVault"
|
|
2113
|
+
}
|
|
2114
|
+
]
|
|
2115
|
+
}
|
|
2116
|
+
},
|
|
2117
|
+
{
|
|
2118
|
+
name: "pending_spend",
|
|
2119
|
+
writable: true,
|
|
2120
|
+
pda: {
|
|
2121
|
+
seeds: [
|
|
2122
|
+
{
|
|
2123
|
+
kind: "const",
|
|
2124
|
+
value: [
|
|
2125
|
+
112,
|
|
2126
|
+
101,
|
|
2127
|
+
110,
|
|
2128
|
+
100,
|
|
2129
|
+
105,
|
|
2130
|
+
110,
|
|
2131
|
+
103
|
|
2132
|
+
]
|
|
2133
|
+
},
|
|
2134
|
+
{
|
|
2135
|
+
kind: "account",
|
|
2136
|
+
path: "vault"
|
|
2137
|
+
},
|
|
2138
|
+
{
|
|
2139
|
+
kind: "account",
|
|
2140
|
+
path: "pending_spend.nonce",
|
|
2141
|
+
account: "PendingSpend"
|
|
2142
|
+
}
|
|
2143
|
+
]
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
],
|
|
2147
|
+
args: []
|
|
2148
|
+
},
|
|
1954
2149
|
{
|
|
1955
2150
|
name: "claim",
|
|
1956
2151
|
discriminator: [
|
|
@@ -2357,6 +2552,104 @@ var credit_vault_default = {
|
|
|
2357
2552
|
],
|
|
2358
2553
|
args: []
|
|
2359
2554
|
},
|
|
2555
|
+
{
|
|
2556
|
+
name: "request_spend",
|
|
2557
|
+
discriminator: [
|
|
2558
|
+
127,
|
|
2559
|
+
12,
|
|
2560
|
+
23,
|
|
2561
|
+
75,
|
|
2562
|
+
137,
|
|
2563
|
+
178,
|
|
2564
|
+
148,
|
|
2565
|
+
71
|
|
2566
|
+
],
|
|
2567
|
+
accounts: [
|
|
2568
|
+
{
|
|
2569
|
+
name: "agent",
|
|
2570
|
+
writable: true,
|
|
2571
|
+
signer: true,
|
|
2572
|
+
relations: [
|
|
2573
|
+
"vault"
|
|
2574
|
+
]
|
|
2575
|
+
},
|
|
2576
|
+
{
|
|
2577
|
+
name: "vault",
|
|
2578
|
+
writable: true,
|
|
2579
|
+
pda: {
|
|
2580
|
+
seeds: [
|
|
2581
|
+
{
|
|
2582
|
+
kind: "const",
|
|
2583
|
+
value: [
|
|
2584
|
+
118,
|
|
2585
|
+
97,
|
|
2586
|
+
117,
|
|
2587
|
+
108,
|
|
2588
|
+
116
|
|
2589
|
+
]
|
|
2590
|
+
},
|
|
2591
|
+
{
|
|
2592
|
+
kind: "account",
|
|
2593
|
+
path: "vault.owner",
|
|
2594
|
+
account: "CreditVault"
|
|
2595
|
+
},
|
|
2596
|
+
{
|
|
2597
|
+
kind: "account",
|
|
2598
|
+
path: "vault.agent",
|
|
2599
|
+
account: "CreditVault"
|
|
2600
|
+
}
|
|
2601
|
+
]
|
|
2602
|
+
}
|
|
2603
|
+
},
|
|
2604
|
+
{
|
|
2605
|
+
name: "service_token_account",
|
|
2606
|
+
docs: [
|
|
2607
|
+
"The recipient token account. We only need it for its `owner` field",
|
|
2608
|
+
"(the service pubkey we record in PendingSpend); mint constraint is",
|
|
2609
|
+
"belt-and-suspenders since `approve_spend` re-checks both."
|
|
2610
|
+
]
|
|
2611
|
+
},
|
|
2612
|
+
{
|
|
2613
|
+
name: "pending_spend",
|
|
2614
|
+
writable: true,
|
|
2615
|
+
pda: {
|
|
2616
|
+
seeds: [
|
|
2617
|
+
{
|
|
2618
|
+
kind: "const",
|
|
2619
|
+
value: [
|
|
2620
|
+
112,
|
|
2621
|
+
101,
|
|
2622
|
+
110,
|
|
2623
|
+
100,
|
|
2624
|
+
105,
|
|
2625
|
+
110,
|
|
2626
|
+
103
|
|
2627
|
+
]
|
|
2628
|
+
},
|
|
2629
|
+
{
|
|
2630
|
+
kind: "account",
|
|
2631
|
+
path: "vault"
|
|
2632
|
+
},
|
|
2633
|
+
{
|
|
2634
|
+
kind: "account",
|
|
2635
|
+
path: "vault.pending_count",
|
|
2636
|
+
account: "CreditVault"
|
|
2637
|
+
}
|
|
2638
|
+
]
|
|
2639
|
+
}
|
|
2640
|
+
},
|
|
2641
|
+
{
|
|
2642
|
+
name: "system_program",
|
|
2643
|
+
address: "11111111111111111111111111111111"
|
|
2644
|
+
}
|
|
2645
|
+
],
|
|
2646
|
+
args: [
|
|
2647
|
+
{
|
|
2648
|
+
name: "amount_usdc",
|
|
2649
|
+
type: "u64"
|
|
2650
|
+
}
|
|
2651
|
+
]
|
|
2652
|
+
},
|
|
2360
2653
|
{
|
|
2361
2654
|
name: "spend",
|
|
2362
2655
|
discriminator: [
|
|
@@ -2682,6 +2975,19 @@ var credit_vault_default = {
|
|
|
2682
2975
|
70
|
|
2683
2976
|
]
|
|
2684
2977
|
},
|
|
2978
|
+
{
|
|
2979
|
+
name: "PendingSpend",
|
|
2980
|
+
discriminator: [
|
|
2981
|
+
193,
|
|
2982
|
+
205,
|
|
2983
|
+
85,
|
|
2984
|
+
66,
|
|
2985
|
+
25,
|
|
2986
|
+
3,
|
|
2987
|
+
67,
|
|
2988
|
+
134
|
|
2989
|
+
]
|
|
2990
|
+
},
|
|
2685
2991
|
{
|
|
2686
2992
|
name: "SpendPolicy",
|
|
2687
2993
|
discriminator: [
|
|
@@ -2736,6 +3042,32 @@ var credit_vault_default = {
|
|
|
2736
3042
|
161
|
|
2737
3043
|
]
|
|
2738
3044
|
},
|
|
3045
|
+
{
|
|
3046
|
+
name: "SpendRejected",
|
|
3047
|
+
discriminator: [
|
|
3048
|
+
22,
|
|
3049
|
+
233,
|
|
3050
|
+
208,
|
|
3051
|
+
109,
|
|
3052
|
+
202,
|
|
3053
|
+
231,
|
|
3054
|
+
175,
|
|
3055
|
+
22
|
|
3056
|
+
]
|
|
3057
|
+
},
|
|
3058
|
+
{
|
|
3059
|
+
name: "SpendRequested",
|
|
3060
|
+
discriminator: [
|
|
3061
|
+
144,
|
|
3062
|
+
207,
|
|
3063
|
+
254,
|
|
3064
|
+
247,
|
|
3065
|
+
81,
|
|
3066
|
+
146,
|
|
3067
|
+
84,
|
|
3068
|
+
87
|
|
3069
|
+
]
|
|
3070
|
+
},
|
|
2739
3071
|
{
|
|
2740
3072
|
name: "Spent",
|
|
2741
3073
|
discriminator: [
|
|
@@ -2852,6 +3184,16 @@ var credit_vault_default = {
|
|
|
2852
3184
|
code: 6009,
|
|
2853
3185
|
name: "PostPayDisabled",
|
|
2854
3186
|
msg: "Post-pay claims are disabled for this vault"
|
|
3187
|
+
},
|
|
3188
|
+
{
|
|
3189
|
+
code: 6010,
|
|
3190
|
+
name: "PendingSpendVaultMismatch",
|
|
3191
|
+
msg: "Pending spend belongs to a different vault"
|
|
3192
|
+
},
|
|
3193
|
+
{
|
|
3194
|
+
code: 6011,
|
|
3195
|
+
name: "PendingNonceOverflow",
|
|
3196
|
+
msg: "Pending spend counter would overflow"
|
|
2855
3197
|
}
|
|
2856
3198
|
],
|
|
2857
3199
|
types: [
|
|
@@ -2940,12 +3282,22 @@ var credit_vault_default = {
|
|
|
2940
3282
|
name: "bump",
|
|
2941
3283
|
type: "u8"
|
|
2942
3284
|
},
|
|
3285
|
+
{
|
|
3286
|
+
name: "pending_count",
|
|
3287
|
+
docs: [
|
|
3288
|
+
"Monotonic counter used as a PDA seed for PendingSpend accounts so",
|
|
3289
|
+
"every approval request gets a unique deterministic address.",
|
|
3290
|
+
"Borrowed 8 bytes from the original 64-byte padding so the account",
|
|
3291
|
+
"size stays at `ACCOUNT_SIZE` and existing vaults need no migration."
|
|
3292
|
+
],
|
|
3293
|
+
type: "u64"
|
|
3294
|
+
},
|
|
2943
3295
|
{
|
|
2944
3296
|
name: "_padding",
|
|
2945
3297
|
type: {
|
|
2946
3298
|
array: [
|
|
2947
3299
|
"u8",
|
|
2948
|
-
|
|
3300
|
+
56
|
|
2949
3301
|
]
|
|
2950
3302
|
}
|
|
2951
3303
|
}
|
|
@@ -2980,6 +3332,65 @@ var credit_vault_default = {
|
|
|
2980
3332
|
]
|
|
2981
3333
|
}
|
|
2982
3334
|
},
|
|
3335
|
+
{
|
|
3336
|
+
name: "PendingSpend",
|
|
3337
|
+
docs: [
|
|
3338
|
+
"A spend request that exceeded one of the policy's rate limits. The agent",
|
|
3339
|
+
"creates this account by calling `request_spend`; the owner reviews from",
|
|
3340
|
+
"the mobile Alerts tab and either calls `approve_spend` (PDA-signed CPI",
|
|
3341
|
+
"transfer, account closed) or `cancel_spend` (account closed, no transfer).",
|
|
3342
|
+
"",
|
|
3343
|
+
'Seeded by `["pending", vault, nonce_le]` where `nonce` is the value of',
|
|
3344
|
+
"`vault.pending_count` at request time, so each request has a unique",
|
|
3345
|
+
"deterministic address that both the agent and the owner can derive."
|
|
3346
|
+
],
|
|
3347
|
+
type: {
|
|
3348
|
+
kind: "struct",
|
|
3349
|
+
fields: [
|
|
3350
|
+
{
|
|
3351
|
+
name: "vault",
|
|
3352
|
+
type: "pubkey"
|
|
3353
|
+
},
|
|
3354
|
+
{
|
|
3355
|
+
name: "agent",
|
|
3356
|
+
type: "pubkey"
|
|
3357
|
+
},
|
|
3358
|
+
{
|
|
3359
|
+
name: "service",
|
|
3360
|
+
docs: [
|
|
3361
|
+
"Owner of the destination token account (mirrors how `Spent` records",
|
|
3362
|
+
"service: `service_token_account.owner`)."
|
|
3363
|
+
],
|
|
3364
|
+
type: "pubkey"
|
|
3365
|
+
},
|
|
3366
|
+
{
|
|
3367
|
+
name: "amount_usdc",
|
|
3368
|
+
type: "u64"
|
|
3369
|
+
},
|
|
3370
|
+
{
|
|
3371
|
+
name: "requested_slot",
|
|
3372
|
+
type: "u64"
|
|
3373
|
+
},
|
|
3374
|
+
{
|
|
3375
|
+
name: "nonce",
|
|
3376
|
+
type: "u64"
|
|
3377
|
+
},
|
|
3378
|
+
{
|
|
3379
|
+
name: "bump",
|
|
3380
|
+
type: "u8"
|
|
3381
|
+
},
|
|
3382
|
+
{
|
|
3383
|
+
name: "_padding",
|
|
3384
|
+
type: {
|
|
3385
|
+
array: [
|
|
3386
|
+
"u8",
|
|
3387
|
+
31
|
|
3388
|
+
]
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
]
|
|
3392
|
+
}
|
|
3393
|
+
},
|
|
2983
3394
|
{
|
|
2984
3395
|
name: "PolicyUpdated",
|
|
2985
3396
|
type: {
|
|
@@ -3083,6 +3494,70 @@ var credit_vault_default = {
|
|
|
3083
3494
|
]
|
|
3084
3495
|
}
|
|
3085
3496
|
},
|
|
3497
|
+
{
|
|
3498
|
+
name: "SpendRejected",
|
|
3499
|
+
type: {
|
|
3500
|
+
kind: "struct",
|
|
3501
|
+
fields: [
|
|
3502
|
+
{
|
|
3503
|
+
name: "vault",
|
|
3504
|
+
type: "pubkey"
|
|
3505
|
+
},
|
|
3506
|
+
{
|
|
3507
|
+
name: "owner",
|
|
3508
|
+
type: "pubkey"
|
|
3509
|
+
},
|
|
3510
|
+
{
|
|
3511
|
+
name: "pending_spend",
|
|
3512
|
+
type: "pubkey"
|
|
3513
|
+
},
|
|
3514
|
+
{
|
|
3515
|
+
name: "nonce",
|
|
3516
|
+
type: "u64"
|
|
3517
|
+
},
|
|
3518
|
+
{
|
|
3519
|
+
name: "slot",
|
|
3520
|
+
type: "u64"
|
|
3521
|
+
}
|
|
3522
|
+
]
|
|
3523
|
+
}
|
|
3524
|
+
},
|
|
3525
|
+
{
|
|
3526
|
+
name: "SpendRequested",
|
|
3527
|
+
type: {
|
|
3528
|
+
kind: "struct",
|
|
3529
|
+
fields: [
|
|
3530
|
+
{
|
|
3531
|
+
name: "vault",
|
|
3532
|
+
type: "pubkey"
|
|
3533
|
+
},
|
|
3534
|
+
{
|
|
3535
|
+
name: "agent",
|
|
3536
|
+
type: "pubkey"
|
|
3537
|
+
},
|
|
3538
|
+
{
|
|
3539
|
+
name: "service",
|
|
3540
|
+
type: "pubkey"
|
|
3541
|
+
},
|
|
3542
|
+
{
|
|
3543
|
+
name: "pending_spend",
|
|
3544
|
+
type: "pubkey"
|
|
3545
|
+
},
|
|
3546
|
+
{
|
|
3547
|
+
name: "amount_usdc",
|
|
3548
|
+
type: "u64"
|
|
3549
|
+
},
|
|
3550
|
+
{
|
|
3551
|
+
name: "nonce",
|
|
3552
|
+
type: "u64"
|
|
3553
|
+
},
|
|
3554
|
+
{
|
|
3555
|
+
name: "slot",
|
|
3556
|
+
type: "u64"
|
|
3557
|
+
}
|
|
3558
|
+
]
|
|
3559
|
+
}
|
|
3560
|
+
},
|
|
3086
3561
|
{
|
|
3087
3562
|
name: "Spent",
|
|
3088
3563
|
type: {
|
|
@@ -3267,6 +3742,15 @@ function agentServiceLinkPda(agentProfile, serviceRegistry) {
|
|
|
3267
3742
|
);
|
|
3268
3743
|
return pda;
|
|
3269
3744
|
}
|
|
3745
|
+
function pendingSpendPda(vault, nonce) {
|
|
3746
|
+
const nonceBuf = Buffer.alloc(8);
|
|
3747
|
+
nonceBuf.writeBigUInt64LE(typeof nonce === "bigint" ? nonce : BigInt(nonce));
|
|
3748
|
+
const [pda] = PublicKey.findProgramAddressSync(
|
|
3749
|
+
[Buffer.from("pending"), toPubkey(vault).toBuffer(), nonceBuf],
|
|
3750
|
+
PROGRAM_IDS.creditVault
|
|
3751
|
+
);
|
|
3752
|
+
return pda;
|
|
3753
|
+
}
|
|
3270
3754
|
function receiptUsedPda(receiptHash) {
|
|
3271
3755
|
if (receiptHash.length !== 32) {
|
|
3272
3756
|
throw new Error(`receiptUsedPda expects a 32-byte hash, got ${receiptHash.length}`);
|
|
@@ -3287,6 +3771,207 @@ function reputationProgram(provider) {
|
|
|
3287
3771
|
return new Program(reputation_default, provider);
|
|
3288
3772
|
}
|
|
3289
3773
|
|
|
3774
|
+
// src/pay.ts
|
|
3775
|
+
async function pay(args) {
|
|
3776
|
+
const { agent, service, connection, amountUsdc } = args;
|
|
3777
|
+
const owner = toPubkey(args.owner);
|
|
3778
|
+
if (amountUsdc <= 0) {
|
|
3779
|
+
throw new ZeroAmountError();
|
|
3780
|
+
}
|
|
3781
|
+
if (args.receiptHash.length !== 32) {
|
|
3782
|
+
throw new Error(
|
|
3783
|
+
`pay: receiptHash must be 32 bytes, got ${args.receiptHash.length}`
|
|
3784
|
+
);
|
|
3785
|
+
}
|
|
3786
|
+
const vaultAddr = vaultPda(owner, agent.publicKey);
|
|
3787
|
+
const policyAddr = policyPda(vaultAddr);
|
|
3788
|
+
const provider = buildProvider(connection, agent);
|
|
3789
|
+
const cv = creditVaultProgram(provider);
|
|
3790
|
+
const rep = reputationProgram(provider);
|
|
3791
|
+
const [rawVault, rawPolicy, currentSlot] = await Promise.all([
|
|
3792
|
+
cv.account.creditVault.fetchNullable(vaultAddr),
|
|
3793
|
+
cv.account.spendPolicy.fetchNullable(policyAddr),
|
|
3794
|
+
connection.getSlot()
|
|
3795
|
+
]);
|
|
3796
|
+
if (!rawVault) throw new AccountNotFoundError(vaultAddr.toBase58());
|
|
3797
|
+
if (!rawPolicy) throw new AccountNotFoundError(policyAddr.toBase58());
|
|
3798
|
+
const vault = decodeCreditVault(vaultAddr, rawVault);
|
|
3799
|
+
const policy = decodeSpendPolicy(policyAddr, rawPolicy);
|
|
3800
|
+
guardSpend({
|
|
3801
|
+
vault,
|
|
3802
|
+
policy,
|
|
3803
|
+
service: service.publicKey,
|
|
3804
|
+
amountUsdc,
|
|
3805
|
+
currentSlot
|
|
3806
|
+
});
|
|
3807
|
+
const serviceTokenAccount = getAssociatedTokenAddress(
|
|
3808
|
+
vault.usdc_mint,
|
|
3809
|
+
service.publicKey
|
|
3810
|
+
);
|
|
3811
|
+
const createAtaIx = createAssociatedTokenAccountIdempotentInstruction(
|
|
3812
|
+
agent.publicKey,
|
|
3813
|
+
serviceTokenAccount,
|
|
3814
|
+
service.publicKey,
|
|
3815
|
+
vault.usdc_mint
|
|
3816
|
+
);
|
|
3817
|
+
const agentProfile = agentProfilePda(agent.publicKey);
|
|
3818
|
+
const serviceRegistry = serviceRegistryPda(service.publicKey);
|
|
3819
|
+
const link = agentServiceLinkPda(agentProfile, serviceRegistry);
|
|
3820
|
+
const receipt = receiptUsedPda(args.receiptHash);
|
|
3821
|
+
const spendBuilder = cv.methods.spend(new BN(amountUsdc)).accounts({
|
|
3822
|
+
agent: agent.publicKey,
|
|
3823
|
+
vault: vaultAddr,
|
|
3824
|
+
policy: policyAddr,
|
|
3825
|
+
vaultTokenAccount: vault.vault_token_account,
|
|
3826
|
+
serviceTokenAccount,
|
|
3827
|
+
tokenProgram: TOKEN_PROGRAM_ID
|
|
3828
|
+
});
|
|
3829
|
+
const recordBuilder = rep.methods.recordPayment(new BN(amountUsdc), args.receiptHash).accounts({
|
|
3830
|
+
service: service.publicKey,
|
|
3831
|
+
agentProfile,
|
|
3832
|
+
serviceRegistry,
|
|
3833
|
+
agentServiceLink: link,
|
|
3834
|
+
receiptUsed: receipt,
|
|
3835
|
+
systemProgram: SystemProgram.programId
|
|
3836
|
+
});
|
|
3837
|
+
const spendIx = await spendBuilder.instruction();
|
|
3838
|
+
const recordIx = await recordBuilder.instruction();
|
|
3839
|
+
const tx = new Transaction().add(createAtaIx, spendIx, recordIx);
|
|
3840
|
+
try {
|
|
3841
|
+
const signature = await sendAndConfirmTransaction(
|
|
3842
|
+
connection,
|
|
3843
|
+
tx,
|
|
3844
|
+
[agent, service],
|
|
3845
|
+
{ commitment: "confirmed" }
|
|
3846
|
+
);
|
|
3847
|
+
return { signature };
|
|
3848
|
+
} catch (err) {
|
|
3849
|
+
throw mapPayError(err, {
|
|
3850
|
+
service: service.publicKey,
|
|
3851
|
+
amountUsdc,
|
|
3852
|
+
vault,
|
|
3853
|
+
policy,
|
|
3854
|
+
receiptHash: args.receiptHash
|
|
3855
|
+
});
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
function mapPayError(err, ctx) {
|
|
3859
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3860
|
+
if (/already in use/i.test(message)) {
|
|
3861
|
+
return new ReceiptAlreadyRecordedError(ctx.receiptHash);
|
|
3862
|
+
}
|
|
3863
|
+
if (!(err instanceof AnchorError)) return err;
|
|
3864
|
+
switch (err.error.errorCode.number) {
|
|
3865
|
+
case 6001:
|
|
3866
|
+
return new ZeroAmountError();
|
|
3867
|
+
case 6002:
|
|
3868
|
+
return new VaultFrozenError();
|
|
3869
|
+
case 6003:
|
|
3870
|
+
return new NotWhitelistedError(ctx.service.toBase58());
|
|
3871
|
+
case 6004:
|
|
3872
|
+
return new PerTxLimitExceededError(ctx.amountUsdc, ctx.policy.per_tx_limit_usdc);
|
|
3873
|
+
case 6005:
|
|
3874
|
+
return new HourlyLimitExceededError(
|
|
3875
|
+
ctx.amountUsdc,
|
|
3876
|
+
ctx.policy.hourly_window_spent_usdc,
|
|
3877
|
+
ctx.policy.hourly_limit_usdc
|
|
3878
|
+
);
|
|
3879
|
+
case 6006:
|
|
3880
|
+
return new LifetimeLimitExceededError(
|
|
3881
|
+
ctx.amountUsdc,
|
|
3882
|
+
ctx.vault.total_spent,
|
|
3883
|
+
ctx.policy.lifetime_limit_usdc
|
|
3884
|
+
);
|
|
3885
|
+
// Reputation errors:
|
|
3886
|
+
case 6e3:
|
|
3887
|
+
return new RecordPaymentError("counter overflow on chain");
|
|
3888
|
+
case 6011:
|
|
3889
|
+
return new ServiceInactiveError(ctx.service.toBase58());
|
|
3890
|
+
default:
|
|
3891
|
+
return err;
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3894
|
+
async function requestSpend(args) {
|
|
3895
|
+
const { agent, connection, amountUsdc } = args;
|
|
3896
|
+
const owner = toPubkey(args.owner);
|
|
3897
|
+
const service = toPubkey(args.service);
|
|
3898
|
+
if (amountUsdc <= 0) {
|
|
3899
|
+
throw new Error("requestSpend: amountUsdc must be > 0");
|
|
3900
|
+
}
|
|
3901
|
+
const vaultAddr = vaultPda(owner, agent.publicKey);
|
|
3902
|
+
const provider = buildProvider(connection, agent);
|
|
3903
|
+
const cv = creditVaultProgram(provider);
|
|
3904
|
+
const rawVault = await cv.account.creditVault.fetchNullable(vaultAddr);
|
|
3905
|
+
if (!rawVault) throw new AccountNotFoundError(vaultAddr.toBase58());
|
|
3906
|
+
const vault = decodeCreditVault(vaultAddr, rawVault);
|
|
3907
|
+
const nonce = vault.pending_count;
|
|
3908
|
+
const pendingSpend = pendingSpendPda(vaultAddr, nonce);
|
|
3909
|
+
const serviceTokenAccount = getAssociatedTokenAddress(
|
|
3910
|
+
vault.usdc_mint,
|
|
3911
|
+
service
|
|
3912
|
+
);
|
|
3913
|
+
const signature = await cv.methods.requestSpend(new BN(amountUsdc)).accounts({
|
|
3914
|
+
agent: agent.publicKey,
|
|
3915
|
+
vault: vaultAddr,
|
|
3916
|
+
serviceTokenAccount,
|
|
3917
|
+
pendingSpend,
|
|
3918
|
+
systemProgram: SystemProgram.programId
|
|
3919
|
+
}).signers([agent]).rpc();
|
|
3920
|
+
return { signature, pendingSpend, nonce };
|
|
3921
|
+
}
|
|
3922
|
+
var NAME_BYTES = 32;
|
|
3923
|
+
var URI_BYTES = 128;
|
|
3924
|
+
async function registerService(args) {
|
|
3925
|
+
const { sponsor, service, connection } = args;
|
|
3926
|
+
if (args.name.length === 0) {
|
|
3927
|
+
throw new Error("registerService: name must not be empty");
|
|
3928
|
+
}
|
|
3929
|
+
if (Buffer.byteLength(args.name, "utf8") > NAME_BYTES) {
|
|
3930
|
+
throw new Error(
|
|
3931
|
+
`registerService: name exceeds ${NAME_BYTES} bytes (got ${Buffer.byteLength(args.name, "utf8")})`
|
|
3932
|
+
);
|
|
3933
|
+
}
|
|
3934
|
+
const uri = args.serviceUri ?? "";
|
|
3935
|
+
if (Buffer.byteLength(uri, "utf8") > URI_BYTES) {
|
|
3936
|
+
throw new Error(
|
|
3937
|
+
`registerService: serviceUri exceeds ${URI_BYTES} bytes (got ${Buffer.byteLength(uri, "utf8")})`
|
|
3938
|
+
);
|
|
3939
|
+
}
|
|
3940
|
+
const registry = serviceRegistryPda(service.publicKey);
|
|
3941
|
+
const provider = buildProvider(connection, sponsor);
|
|
3942
|
+
const rep = reputationProgram(provider);
|
|
3943
|
+
const signature = await rep.methods.registerService(
|
|
3944
|
+
packFixed(args.name, NAME_BYTES),
|
|
3945
|
+
categoryArg(args.category),
|
|
3946
|
+
packFixed(uri, URI_BYTES)
|
|
3947
|
+
).accounts({
|
|
3948
|
+
sponsor: sponsor.publicKey,
|
|
3949
|
+
service: service.publicKey,
|
|
3950
|
+
serviceRegistry: registry,
|
|
3951
|
+
systemProgram: SystemProgram.programId
|
|
3952
|
+
}).signers([sponsor, service]).rpc();
|
|
3953
|
+
return { signature };
|
|
3954
|
+
}
|
|
3955
|
+
function packFixed(s, length) {
|
|
3956
|
+
const buf = Buffer.alloc(length);
|
|
3957
|
+
buf.write(s, 0, "utf8");
|
|
3958
|
+
return Array.from(buf);
|
|
3959
|
+
}
|
|
3960
|
+
function categoryArg(c) {
|
|
3961
|
+
switch (c) {
|
|
3962
|
+
case "DataFeed":
|
|
3963
|
+
return { dataFeed: {} };
|
|
3964
|
+
case "Compute":
|
|
3965
|
+
return { compute: {} };
|
|
3966
|
+
case "Swap":
|
|
3967
|
+
return { swap: {} };
|
|
3968
|
+
case "Rpc":
|
|
3969
|
+
return { rpc: {} };
|
|
3970
|
+
case "Other":
|
|
3971
|
+
return { other: {} };
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3290
3975
|
// src/client.ts
|
|
3291
3976
|
var DEFAULT_API_BASE = "http://localhost:8080";
|
|
3292
3977
|
var AgentFuel = class {
|
|
@@ -3385,6 +4070,38 @@ var AgentFuel = class {
|
|
|
3385
4070
|
throw mapSpendError(err, { service, amountUsdc, vault, policy });
|
|
3386
4071
|
}
|
|
3387
4072
|
}
|
|
4073
|
+
/// Atomic spend + record_payment in one transaction. Use this instead
|
|
4074
|
+
/// of `spend()` + `recordPayment()` when you want the vault burn and
|
|
4075
|
+
/// the reputation accrual to be all-or-nothing. The service keypair
|
|
4076
|
+
/// co-signs.
|
|
4077
|
+
async pay(args) {
|
|
4078
|
+
return pay({
|
|
4079
|
+
agent: this.agent,
|
|
4080
|
+
owner: this.resolveOwner(args.owner),
|
|
4081
|
+
service: args.service,
|
|
4082
|
+
amountUsdc: args.amountUsdc,
|
|
4083
|
+
receiptHash: args.receiptHash,
|
|
4084
|
+
connection: this.connection
|
|
4085
|
+
});
|
|
4086
|
+
}
|
|
4087
|
+
/// Submit an over-limit spend request the owner can approve from the
|
|
4088
|
+
/// mobile app. Returns the `pendingSpend` PDA so the bot can poll for
|
|
4089
|
+
/// resolution.
|
|
4090
|
+
async requestSpend(args) {
|
|
4091
|
+
return requestSpend({
|
|
4092
|
+
agent: this.agent,
|
|
4093
|
+
owner: this.resolveOwner(args.owner),
|
|
4094
|
+
service: args.service,
|
|
4095
|
+
amountUsdc: args.amountUsdc,
|
|
4096
|
+
connection: this.connection
|
|
4097
|
+
});
|
|
4098
|
+
}
|
|
4099
|
+
/// Register a service on chain. The `sponsor` (typically `this.agent`'s
|
|
4100
|
+
/// owner wallet) pays rent; the `service` keypair is the long-lived
|
|
4101
|
+
/// identity that will co-sign every future `record_payment`.
|
|
4102
|
+
async registerService(args) {
|
|
4103
|
+
return registerService({ ...args, connection: this.connection });
|
|
4104
|
+
}
|
|
3388
4105
|
/// Triggers an on-chain recomputation of the agent's reputation score.
|
|
3389
4106
|
/// Permissionless — any signer can call it; we use the agent itself since
|
|
3390
4107
|
/// the SDK already has its keypair available and it already pays tx fees
|
|
@@ -3580,6 +4297,6 @@ function truncate(s) {
|
|
|
3580
4297
|
return s.length > 80 ? `${s.slice(0, 80)}\u2026` : s;
|
|
3581
4298
|
}
|
|
3582
4299
|
|
|
3583
|
-
export { ASSOCIATED_TOKEN_PROGRAM_ID, AccountNotFoundError, AgentFuel, AgentFuelError, HourlyLimitExceededError, HttpError, LifetimeLimitExceededError, NotWhitelistedError, OwnerNotConfiguredError, PROGRAM_IDS, PaymentParseError, PerTxLimitExceededError, ReceiptAlreadyRecordedError, RecordPaymentError, SLOTS_PER_HOUR, ServiceInactiveError, SpendPolicyError, TOKEN_PROGRAM_ID, VaultFrozenError, ZeroAmountError, agentProfilePda, agentServiceLinkPda, createAssociatedTokenAccountIdempotentInstruction, getAssociatedTokenAddress, paymentRequired, policyPda, receiptUsedPda, recordPayment, serviceRegistryPda, subscribeService, subscribeVault, vaultPda };
|
|
4300
|
+
export { ASSOCIATED_TOKEN_PROGRAM_ID, AccountNotFoundError, AgentFuel, AgentFuelError, HourlyLimitExceededError, HttpError, LifetimeLimitExceededError, NotWhitelistedError, OwnerNotConfiguredError, PROGRAM_IDS, PaymentParseError, PerTxLimitExceededError, ReceiptAlreadyRecordedError, RecordPaymentError, SLOTS_PER_HOUR, ServiceInactiveError, SpendPolicyError, TOKEN_PROGRAM_ID, VaultFrozenError, ZeroAmountError, agentProfilePda, agentServiceLinkPda, createAssociatedTokenAccountIdempotentInstruction, getAssociatedTokenAddress, pay, paymentRequired, pendingSpendPda, policyPda, receiptUsedPda, recordPayment, registerService, requestSpend, serviceRegistryPda, subscribeService, subscribeVault, vaultPda };
|
|
3584
4301
|
//# sourceMappingURL=index.js.map
|
|
3585
4302
|
//# sourceMappingURL=index.js.map
|