@satoshai/kit 0.4.1 → 0.5.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 +23 -0
- package/dist/index.cjs +239 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -4
- package/dist/index.d.ts +73 -4
- package/dist/index.js +239 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { PostCondition, PostConditionMode, ClarityValue } from '@stacks/transactions';
|
|
3
|
+
import { ClarityAbi, ExtractAbiFunctionNames, Pretty, ExtractAbiFunction, ClarityAbiArgToPrimitiveTypeValue } from 'clarity-abitype';
|
|
4
|
+
export { ClarityAbi } from 'clarity-abitype';
|
|
3
5
|
|
|
4
6
|
declare const SUPPORTED_STACKS_WALLETS: readonly ["xverse", "leather", "asigna", "fordefi", "wallet-connect", "okx"];
|
|
5
7
|
type SupportedStacksWallet = (typeof SUPPORTED_STACKS_WALLETS)[number];
|
|
@@ -122,26 +124,82 @@ declare const useSignMessage: () => {
|
|
|
122
124
|
status: MutationStatus;
|
|
123
125
|
};
|
|
124
126
|
|
|
127
|
+
interface TransferSTXVariables {
|
|
128
|
+
recipient: string;
|
|
129
|
+
amount: bigint | number | string;
|
|
130
|
+
memo?: string;
|
|
131
|
+
fee?: bigint | number | string;
|
|
132
|
+
nonce?: bigint | number | string;
|
|
133
|
+
}
|
|
134
|
+
interface TransferSTXOptions {
|
|
135
|
+
onSuccess?: (txid: string) => void;
|
|
136
|
+
onError?: (error: Error) => void;
|
|
137
|
+
onSettled?: (txid: string | undefined, error: Error | null) => void;
|
|
138
|
+
}
|
|
139
|
+
declare const useTransferSTX: () => {
|
|
140
|
+
transferSTX: (variables: TransferSTXVariables, options?: TransferSTXOptions) => void;
|
|
141
|
+
transferSTXAsync: (variables: TransferSTXVariables) => Promise<string>;
|
|
142
|
+
reset: () => void;
|
|
143
|
+
data: string | undefined;
|
|
144
|
+
error: Error | null;
|
|
145
|
+
isError: boolean;
|
|
146
|
+
isIdle: boolean;
|
|
147
|
+
isPending: boolean;
|
|
148
|
+
isSuccess: boolean;
|
|
149
|
+
status: MutationStatus;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/** Contract principal string in the format `address.contract-name` */
|
|
153
|
+
type TraitReference = `${string}.${string}`;
|
|
154
|
+
/** Union of public function names from a Clarity ABI */
|
|
155
|
+
type PublicFunctionName<TAbi extends ClarityAbi> = ExtractAbiFunctionNames<TAbi, 'public'>;
|
|
156
|
+
/** Named args object for a specific public function, derived from ABI */
|
|
157
|
+
type PublicFunctionArgs<TAbi extends ClarityAbi, TFn extends ExtractAbiFunctionNames<TAbi, 'public'>> = Pretty<{
|
|
158
|
+
[K in ExtractAbiFunction<TAbi, TFn, 'public'>['args'][number] as K['name']]: ClarityAbiArgToPrimitiveTypeValue<K>;
|
|
159
|
+
}>;
|
|
160
|
+
|
|
125
161
|
interface PostConditionConfig {
|
|
126
162
|
postConditions: PostCondition[];
|
|
127
163
|
mode: PostConditionMode;
|
|
128
164
|
}
|
|
129
|
-
|
|
165
|
+
/** Typed mode: ABI present, args is a named object with autocomplete. */
|
|
166
|
+
interface TypedWriteContractVariables<TAbi extends ClarityAbi, TFn extends ExtractAbiFunctionNames<TAbi, 'public'>> {
|
|
167
|
+
abi: TAbi;
|
|
168
|
+
address: string;
|
|
169
|
+
contract: string;
|
|
170
|
+
functionName: TFn;
|
|
171
|
+
args: PublicFunctionArgs<TAbi, TFn>;
|
|
172
|
+
pc: PostConditionConfig;
|
|
173
|
+
}
|
|
174
|
+
/** Untyped mode: no ABI, args is ClarityValue[] (original behavior). */
|
|
175
|
+
interface UntypedWriteContractVariables {
|
|
130
176
|
address: string;
|
|
131
177
|
contract: string;
|
|
132
178
|
functionName: string;
|
|
133
179
|
args: ClarityValue[];
|
|
134
180
|
pc: PostConditionConfig;
|
|
135
181
|
}
|
|
182
|
+
/** Backward-compatible alias for the untyped variant. */
|
|
183
|
+
type WriteContractVariables = UntypedWriteContractVariables;
|
|
136
184
|
interface WriteContractOptions {
|
|
137
185
|
onSuccess?: (txHash: string) => void;
|
|
138
186
|
onError?: (error: Error) => void;
|
|
139
187
|
onSettled?: (txHash: string | undefined, error: Error | null) => void;
|
|
140
188
|
}
|
|
189
|
+
/** Overloaded async function: typed mode (with ABI) or untyped mode. */
|
|
190
|
+
interface WriteContractAsyncFn {
|
|
191
|
+
<const TAbi extends ClarityAbi, TFn extends ExtractAbiFunctionNames<TAbi, 'public'>>(variables: TypedWriteContractVariables<TAbi, TFn>): Promise<string>;
|
|
192
|
+
(variables: UntypedWriteContractVariables): Promise<string>;
|
|
193
|
+
}
|
|
194
|
+
/** Overloaded fire-and-forget function: typed mode or untyped mode. */
|
|
195
|
+
interface WriteContractFn {
|
|
196
|
+
<const TAbi extends ClarityAbi, TFn extends ExtractAbiFunctionNames<TAbi, 'public'>>(variables: TypedWriteContractVariables<TAbi, TFn>, options?: WriteContractOptions): void;
|
|
197
|
+
(variables: UntypedWriteContractVariables, options?: WriteContractOptions): void;
|
|
198
|
+
}
|
|
141
199
|
|
|
142
200
|
declare const useWriteContract: () => {
|
|
143
|
-
writeContract:
|
|
144
|
-
writeContractAsync:
|
|
201
|
+
writeContract: WriteContractFn;
|
|
202
|
+
writeContractAsync: WriteContractAsyncFn;
|
|
145
203
|
reset: () => void;
|
|
146
204
|
data: string | undefined;
|
|
147
205
|
error: Error | null;
|
|
@@ -174,4 +232,15 @@ interface StacksWallets {
|
|
|
174
232
|
}
|
|
175
233
|
declare const getStacksWallets: () => StacksWallets;
|
|
176
234
|
|
|
177
|
-
|
|
235
|
+
/** Pre-bind ABI + address + contract for reuse with useWriteContract. */
|
|
236
|
+
declare function createContractConfig<const TAbi extends ClarityAbi>(config: {
|
|
237
|
+
abi: TAbi;
|
|
238
|
+
address: string;
|
|
239
|
+
contract: string;
|
|
240
|
+
}): {
|
|
241
|
+
abi: TAbi;
|
|
242
|
+
address: string;
|
|
243
|
+
contract: string;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export { type ConnectOptions, type MutationStatus, type PostConditionConfig, type PublicFunctionArgs, type PublicFunctionName, SUPPORTED_STACKS_WALLETS, type SignMessageData, type SignMessageOptions, type SignMessageVariables, type StacksChain, StacksWalletProvider, type StacksWallets, type SupportedStacksWallet, type TraitReference, type TransferSTXOptions, type TransferSTXVariables, type TypedWriteContractVariables, type UntypedWriteContractVariables, type WalletConnectMetadata, type WalletContextValue, type WalletInfo, type WalletState, type WriteContractOptions, type WriteContractVariables, createContractConfig, getLocalStorageWallet, getNetworkFromAddress, getStacksWallets, useAddress, useBnsName, useConnect, useDisconnect, useSignMessage, useTransferSTX, useWallets, useWriteContract };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WalletConnect, DEFAULT_PROVIDERS, WALLET_CONNECT_PROVIDER, clearSelectedProviderId, request, getSelectedProviderId, getSelectedProvider, setSelectedProviderId } from '@stacks/connect';
|
|
2
2
|
import { createContext, useState, useRef, useEffect, useCallback, useMemo, useContext } from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
|
-
import { PostConditionMode, postConditionToHex, cvToHex } from '@stacks/transactions';
|
|
4
|
+
import { PostConditionMode, postConditionToHex, cvToHex, noneCV, contractPrincipalCV, standardPrincipalCV, boolCV, intCV, uintCV, bufferCV, stringAsciiCV, stringUtf8CV, someCV, listCV, tupleCV } from '@stacks/transactions';
|
|
5
5
|
import { getPrimaryName } from 'bns-v2-sdk';
|
|
6
6
|
|
|
7
7
|
// src/constants/stacks-provider-mapping.ts
|
|
@@ -761,10 +761,239 @@ var getNetworkFromAddress = (address) => {
|
|
|
761
761
|
}
|
|
762
762
|
throw new Error(`Invalid Stacks address: ${address}`);
|
|
763
763
|
};
|
|
764
|
+
|
|
765
|
+
// src/hooks/use-transfer-stx.ts
|
|
766
|
+
var useTransferSTX = () => {
|
|
767
|
+
const { isConnected, address, provider } = useAddress();
|
|
768
|
+
const [data, setData] = useState(void 0);
|
|
769
|
+
const [error, setError] = useState(null);
|
|
770
|
+
const [status, setStatus] = useState("idle");
|
|
771
|
+
const transferSTXAsync = useCallback(
|
|
772
|
+
async (variables) => {
|
|
773
|
+
if (!isConnected || !address) {
|
|
774
|
+
throw new Error("Wallet is not connected");
|
|
775
|
+
}
|
|
776
|
+
setStatus("pending");
|
|
777
|
+
setError(null);
|
|
778
|
+
setData(void 0);
|
|
779
|
+
try {
|
|
780
|
+
if (provider === "okx") {
|
|
781
|
+
if (!window.okxwallet) {
|
|
782
|
+
throw new Error("OKX wallet not found");
|
|
783
|
+
}
|
|
784
|
+
const response2 = await window.okxwallet.stacks.signTransaction({
|
|
785
|
+
txType: "token_transfer",
|
|
786
|
+
recipient: variables.recipient,
|
|
787
|
+
amount: String(variables.amount),
|
|
788
|
+
memo: variables.memo ?? "",
|
|
789
|
+
stxAddress: address,
|
|
790
|
+
anchorMode: 3
|
|
791
|
+
});
|
|
792
|
+
setData(response2.txHash);
|
|
793
|
+
setStatus("success");
|
|
794
|
+
return response2.txHash;
|
|
795
|
+
}
|
|
796
|
+
const response = await request("stx_transferStx", {
|
|
797
|
+
recipient: variables.recipient,
|
|
798
|
+
amount: variables.amount,
|
|
799
|
+
...variables.memo !== void 0 && {
|
|
800
|
+
memo: variables.memo
|
|
801
|
+
},
|
|
802
|
+
...variables.fee !== void 0 && {
|
|
803
|
+
fee: variables.fee
|
|
804
|
+
},
|
|
805
|
+
...variables.nonce !== void 0 && {
|
|
806
|
+
nonce: variables.nonce
|
|
807
|
+
},
|
|
808
|
+
network: getNetworkFromAddress(address)
|
|
809
|
+
});
|
|
810
|
+
if (!response.txid) {
|
|
811
|
+
throw new Error("No transaction ID returned");
|
|
812
|
+
}
|
|
813
|
+
setData(response.txid);
|
|
814
|
+
setStatus("success");
|
|
815
|
+
return response.txid;
|
|
816
|
+
} catch (err) {
|
|
817
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
818
|
+
setError(error2);
|
|
819
|
+
setStatus("error");
|
|
820
|
+
throw error2;
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
[isConnected, address, provider]
|
|
824
|
+
);
|
|
825
|
+
const transferSTX = useCallback(
|
|
826
|
+
(variables, options) => {
|
|
827
|
+
transferSTXAsync(variables).then((txid) => {
|
|
828
|
+
options?.onSuccess?.(txid);
|
|
829
|
+
options?.onSettled?.(txid, null);
|
|
830
|
+
}).catch((error2) => {
|
|
831
|
+
options?.onError?.(error2);
|
|
832
|
+
options?.onSettled?.(void 0, error2);
|
|
833
|
+
});
|
|
834
|
+
},
|
|
835
|
+
[transferSTXAsync]
|
|
836
|
+
);
|
|
837
|
+
const reset = useCallback(() => {
|
|
838
|
+
setData(void 0);
|
|
839
|
+
setError(null);
|
|
840
|
+
setStatus("idle");
|
|
841
|
+
}, []);
|
|
842
|
+
return useMemo(
|
|
843
|
+
() => ({
|
|
844
|
+
transferSTX,
|
|
845
|
+
transferSTXAsync,
|
|
846
|
+
reset,
|
|
847
|
+
data,
|
|
848
|
+
error,
|
|
849
|
+
isError: status === "error",
|
|
850
|
+
isIdle: status === "idle",
|
|
851
|
+
isPending: status === "pending",
|
|
852
|
+
isSuccess: status === "success",
|
|
853
|
+
status
|
|
854
|
+
}),
|
|
855
|
+
[transferSTX, transferSTXAsync, reset, data, error, status]
|
|
856
|
+
);
|
|
857
|
+
};
|
|
858
|
+
function toClarityValue(value, abiType) {
|
|
859
|
+
if (typeof abiType === "string") {
|
|
860
|
+
switch (abiType) {
|
|
861
|
+
case "uint128": {
|
|
862
|
+
if (typeof value !== "bigint") {
|
|
863
|
+
throw new Error(
|
|
864
|
+
`@satoshai/kit: Expected bigint (uint128), got ${typeof value}`
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
return uintCV(value);
|
|
868
|
+
}
|
|
869
|
+
case "int128": {
|
|
870
|
+
if (typeof value !== "bigint") {
|
|
871
|
+
throw new Error(
|
|
872
|
+
`@satoshai/kit: Expected bigint (int128), got ${typeof value}`
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
return intCV(value);
|
|
876
|
+
}
|
|
877
|
+
case "bool": {
|
|
878
|
+
if (typeof value !== "boolean") {
|
|
879
|
+
throw new Error(
|
|
880
|
+
`@satoshai/kit: Expected boolean (bool), got ${typeof value}`
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
return boolCV(value);
|
|
884
|
+
}
|
|
885
|
+
case "principal":
|
|
886
|
+
case "trait_reference": {
|
|
887
|
+
if (typeof value !== "string") {
|
|
888
|
+
throw new Error(
|
|
889
|
+
`@satoshai/kit: Expected string (${abiType}), got ${typeof value}`
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
if (value.includes(".")) {
|
|
893
|
+
const [addr, ...rest] = value.split(".");
|
|
894
|
+
return contractPrincipalCV(addr, rest.join("."));
|
|
895
|
+
}
|
|
896
|
+
return standardPrincipalCV(value);
|
|
897
|
+
}
|
|
898
|
+
case "none":
|
|
899
|
+
return noneCV();
|
|
900
|
+
default:
|
|
901
|
+
throw new Error(
|
|
902
|
+
`@satoshai/kit: Unsupported ABI type "${abiType}"`
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if ("buffer" in abiType) {
|
|
907
|
+
if (!(value instanceof Uint8Array)) {
|
|
908
|
+
throw new Error(
|
|
909
|
+
`@satoshai/kit: Expected Uint8Array (buffer), got ${typeof value}`
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
return bufferCV(value);
|
|
913
|
+
}
|
|
914
|
+
if ("string-ascii" in abiType) {
|
|
915
|
+
if (typeof value !== "string") {
|
|
916
|
+
throw new Error(
|
|
917
|
+
`@satoshai/kit: Expected string (string-ascii), got ${typeof value}`
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
return stringAsciiCV(value);
|
|
921
|
+
}
|
|
922
|
+
if ("string-utf8" in abiType) {
|
|
923
|
+
if (typeof value !== "string") {
|
|
924
|
+
throw new Error(
|
|
925
|
+
`@satoshai/kit: Expected string (string-utf8), got ${typeof value}`
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
return stringUtf8CV(value);
|
|
929
|
+
}
|
|
930
|
+
if ("optional" in abiType) {
|
|
931
|
+
if (value === null || value === void 0) return noneCV();
|
|
932
|
+
return someCV(toClarityValue(value, abiType.optional));
|
|
933
|
+
}
|
|
934
|
+
if ("list" in abiType) {
|
|
935
|
+
if (!Array.isArray(value)) {
|
|
936
|
+
throw new Error(
|
|
937
|
+
`@satoshai/kit: Expected array (list), got ${typeof value}`
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
const listType = abiType.list;
|
|
941
|
+
return listCV(
|
|
942
|
+
value.map((item) => toClarityValue(item, listType.type))
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
if ("tuple" in abiType) {
|
|
946
|
+
if (typeof value !== "object" || value === null) {
|
|
947
|
+
throw new Error(
|
|
948
|
+
`@satoshai/kit: Expected object (tuple), got ${value === null ? "null" : typeof value}`
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
const entries = abiType.tuple;
|
|
952
|
+
const obj = value;
|
|
953
|
+
const result = {};
|
|
954
|
+
for (const entry of entries) {
|
|
955
|
+
result[entry.name] = toClarityValue(obj[entry.name], entry.type);
|
|
956
|
+
}
|
|
957
|
+
return tupleCV(result);
|
|
958
|
+
}
|
|
959
|
+
throw new Error(
|
|
960
|
+
`@satoshai/kit: Unsupported ABI type: ${JSON.stringify(abiType)}`
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
function namedArgsToClarityValues(args, abiArgs) {
|
|
964
|
+
return abiArgs.map((abiArg) => {
|
|
965
|
+
if (!(abiArg.name in args)) {
|
|
966
|
+
throw new Error(
|
|
967
|
+
`@satoshai/kit: Missing argument "${abiArg.name}"`
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
return toClarityValue(
|
|
971
|
+
args[abiArg.name],
|
|
972
|
+
abiArg.type
|
|
973
|
+
);
|
|
974
|
+
});
|
|
975
|
+
}
|
|
764
976
|
var preparePostConditionsForOKX = (postConditions) => postConditions.map((pc) => postConditionToHex(pc));
|
|
765
977
|
var prepareArgsForOKX = (args) => args.map((arg) => cvToHex(arg));
|
|
766
978
|
|
|
767
979
|
// src/hooks/use-write-contract/use-write-contract.ts
|
|
980
|
+
function resolveArgs(variables) {
|
|
981
|
+
if (!variables.abi) {
|
|
982
|
+
return variables.args;
|
|
983
|
+
}
|
|
984
|
+
const fn = variables.abi.functions.find(
|
|
985
|
+
(f) => f.name === variables.functionName && f.access === "public"
|
|
986
|
+
);
|
|
987
|
+
if (!fn) {
|
|
988
|
+
throw new Error(
|
|
989
|
+
`@satoshai/kit: Public function "${variables.functionName}" not found in ABI`
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
return namedArgsToClarityValues(
|
|
993
|
+
variables.args,
|
|
994
|
+
fn.args
|
|
995
|
+
);
|
|
996
|
+
}
|
|
768
997
|
var useWriteContract = () => {
|
|
769
998
|
const { isConnected, address, provider } = useAddress();
|
|
770
999
|
const [data, setData] = useState(void 0);
|
|
@@ -778,6 +1007,7 @@ var useWriteContract = () => {
|
|
|
778
1007
|
setStatus("pending");
|
|
779
1008
|
setError(null);
|
|
780
1009
|
setData(void 0);
|
|
1010
|
+
const resolvedArgs = resolveArgs(variables);
|
|
781
1011
|
try {
|
|
782
1012
|
if (provider === "okx") {
|
|
783
1013
|
if (!window.okxwallet) {
|
|
@@ -787,7 +1017,7 @@ var useWriteContract = () => {
|
|
|
787
1017
|
contractAddress: variables.address,
|
|
788
1018
|
contractName: variables.contract,
|
|
789
1019
|
functionName: variables.functionName,
|
|
790
|
-
functionArgs: prepareArgsForOKX(
|
|
1020
|
+
functionArgs: prepareArgsForOKX(resolvedArgs),
|
|
791
1021
|
postConditions: preparePostConditionsForOKX(
|
|
792
1022
|
variables.pc.postConditions
|
|
793
1023
|
),
|
|
@@ -804,7 +1034,7 @@ var useWriteContract = () => {
|
|
|
804
1034
|
address,
|
|
805
1035
|
contract: `${variables.address}.${variables.contract}`,
|
|
806
1036
|
functionName: variables.functionName,
|
|
807
|
-
functionArgs:
|
|
1037
|
+
functionArgs: resolvedArgs,
|
|
808
1038
|
postConditions: variables.pc.postConditions,
|
|
809
1039
|
postConditionMode: variables.pc.mode === PostConditionMode.Allow ? "allow" : "deny",
|
|
810
1040
|
network: getNetworkFromAddress(address)
|
|
@@ -896,6 +1126,11 @@ var useWallets = () => {
|
|
|
896
1126
|
return useMemo(() => ({ wallets }), [wallets]);
|
|
897
1127
|
};
|
|
898
1128
|
|
|
899
|
-
|
|
1129
|
+
// src/utils/create-contract-config.ts
|
|
1130
|
+
function createContractConfig(config) {
|
|
1131
|
+
return config;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
export { SUPPORTED_STACKS_WALLETS, StacksWalletProvider, createContractConfig, getLocalStorageWallet, getNetworkFromAddress, getStacksWallets, useAddress, useBnsName, useConnect, useDisconnect, useSignMessage, useTransferSTX, useWallets, useWriteContract };
|
|
900
1135
|
//# sourceMappingURL=index.js.map
|
|
901
1136
|
//# sourceMappingURL=index.js.map
|