Skip to content

Commit

Permalink
feat(rpc): add sip-30 schemas/types
Browse files Browse the repository at this point in the history
feat(rpc): add deployContract

feat(rpc): add profile, backwards compat stx_signTransaction
  • Loading branch information
kyranjamie committed Jan 13, 2025
1 parent e68e810 commit 46af901
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 55 deletions.
54 changes: 34 additions & 20 deletions packages/rpc/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,53 @@
import { ValueOf } from '@leather.io/models';

import { DefineSendTransferMethod } from './methods/bitcoin/send-transfer';
import { DefineSignMessageMethod } from './methods/bitcoin/sign-message';
import { DefineSignPsbtMethod } from './methods/bitcoin/sign-psbt';
import { DefineGetAddressesMethod } from './methods/get-addresses';
import { DefineGetInfoMethod } from './methods/get-info';
import { DefineOpenMethod } from './methods/open';
import { DefineOpenSwapMethod } from './methods/open-swap';
import { DefineSendTransferMethod } from './methods/send-transfer';
import { DefineSignMessageMethod } from './methods/sign-message';
import { DefineSignPsbtMethod } from './methods/sign-psbt';
import { DefineStxSignMessageMethod } from './methods/stx-sign-message';
import { DefineStxSignTransactionMethod } from './methods/stx-sign-transaction';
import { DefineStxCallContractMethod } from './methods/stacks/stx-contract-call';
import { DefineStxDeployContractMethod } from './methods/stacks/stx-deploy-contract';
import { DefineStxSignMessageMethod } from './methods/stacks/stx-sign-message';
import { DefineStxSignTransactionMethod } from './methods/stacks/stx-sign-transaction';
import { DefineStxTransferSip10FtMethod } from './methods/stacks/stx-transfer-sip10-ft';
import { DefineStxTransferStxMethod } from './methods/stacks/stx-transfer-stx';
import { DefineStxUpdateProfileMethod } from './methods/stacks/stx-update-profile';
import { DefineSupportedMethods } from './methods/supported-methods';
import { ExtractErrorResponse, ExtractSuccessResponse } from './rpc/schemas';

export * from './rpc/schemas';
export * from './methods/get-info';
export * from './methods/sign-psbt';
export * from './methods/bitcoin/sign-psbt';
export * from './methods/get-addresses';
export * from './methods/send-transfer';
export * from './methods/sign-message';
export * from './methods/stx-sign-message';
export * from './methods/stx-sign-transaction';
export * from './methods/bitcoin/send-transfer';
export * from './methods/bitcoin/sign-message';
export * from './methods/stacks/stx-sign-message';
export * from './methods/stacks/stx-sign-transaction';
export * from './methods/supported-methods';
export * from './methods/open';
export * from './methods/open-swap';

export type LeatherRpcMethodMap = DefineGetInfoMethod &
DefineGetAddressesMethod &
DefineSignPsbtMethod &
DefineSignMessageMethod &
DefineSendTransferMethod &
DefineStxSignMessageMethod &
DefineStxSignTransactionMethod &
DefineOpenSwapMethod &
DefineOpenMethod &
DefineSupportedMethods;
export type LeatherRpcMethodMap =
// Chain agnostic
DefineGetInfoMethod &
DefineOpenMethod &
DefineSupportedMethods &
DefineGetAddressesMethod &
DefineOpenSwapMethod &
// Bitcoin
DefineSignPsbtMethod &
DefineSignMessageMethod &
DefineSendTransferMethod &
// Stacks
DefineStxSignMessageMethod &
DefineStxSignTransactionMethod &
DefineStxCallContractMethod &
DefineStxDeployContractMethod &
DefineStxTransferSip10FtMethod &
DefineStxTransferStxMethod &
DefineStxUpdateProfileMethod;

export type RpcRequests = ValueOf<LeatherRpcMethodMap>['request'];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from 'zod';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../rpc/schemas';
import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';

export const sendTransferRequestParamSchema = z.object({
account: z.number().optional(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AllowAdditionalProperties } from '@leather.io/models';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../rpc/schemas';
import { PaymentTypes } from './get-addresses';
import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';
import { PaymentTypes } from '../get-addresses';

// Implements BIP-322
// https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DefaultNetworkConfigurations } from '@leather.io/models';

import { DefineRpcMethod, RpcParameterByName, RpcRequest, RpcResponse } from '../rpc/schemas';
import { DefineRpcMethod, RpcParameterByName, RpcRequest, RpcResponse } from '../../rpc/schemas';

/**
* DEFAULT -- all inputs, all outputs
Expand Down
97 changes: 97 additions & 0 deletions packages/rpc/src/methods/stacks/_stacks-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { z } from 'zod';

export const stacksTransactionDetailsSchema = z.object({
txid: z.string(),
transaction: z.string(),
});

// Clarity values
export const cvIntSchema = z.object({
type: z.literal('int'),
value: z.string(), // `bigint` compatible
});

export const cvUintSchema = z.object({
type: z.literal('uint'),
value: z.string(), // `bigint` compatible
});

export const cvBufferSchema = z.object({
type: z.literal('buffer'),
value: z.string(), // hex-encoded string
});

export const cvTrueSchema = z.object({
type: z.literal('true'),
});

export const cvFalseSchema = z.object({
type: z.literal('false'),
});

export const cvAddressSchema = z.object({
type: z.literal('address'),
value: z.string(), // Stacks c32-encoded
});

export const cvContractSchema = z.object({
type: z.literal('contract'),
value: z.string(), // Stacks c32-encoded, with contract name suffix
});

export const cvOkSchema = z.object({
type: z.literal('ok'),
value: z.unknown(), // Clarity value
});

export const cvErrSchema = z.object({
type: z.literal('err'),
value: z.unknown(), // Clarity value
});

export const cvNoneSchema = z.object({
type: z.literal('none'),
});

export const cvSomeSchema = z.object({
type: z.literal('some'),
value: z.unknown(), // Clarity value
});

export const cvListSchema = z.object({
type: z.literal('list'),
value: z.array(z.unknown()), // Array of Clarity values
});

export const cvTupleSchema = z.object({
type: z.literal('tuple'),
value: z.record(z.unknown()), // Record of Clarity values
});

export const cvAsciiSchema = z.object({
type: z.literal('ascii'),
value: z.string(), // ASCII-compatible string
});

export const cvUtf8Schema = z.object({
type: z.literal('utf8'),
value: z.string(),
});

export const clarityValueSchema = z.union([
cvIntSchema,
cvUintSchema,
cvBufferSchema,
cvTrueSchema,
cvFalseSchema,
cvAddressSchema,
cvContractSchema,
cvOkSchema,
cvErrSchema,
cvNoneSchema,
cvSomeSchema,
cvListSchema,
cvTupleSchema,
cvAsciiSchema,
cvUtf8Schema,
]);
32 changes: 32 additions & 0 deletions packages/rpc/src/methods/stacks/stx-contract-call.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from 'zod';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';
import { stacksTransactionDetailsSchema } from './_stacks-helpers';

export const stxCallContractMethodName = 'stx_callContract';

type StxCallContractRequestMethodName = typeof stxCallContractMethodName;

// Request
export const stxCallContractRequestParamsSchema = z.object({
contract: z.string(),
asset: z.string(),
amount: z.coerce.number(),
});

export type StxCallContractRequestParams = z.infer<typeof stxCallContractRequestParamsSchema>;

export type StxCallContractRequest = RpcRequest<
StxCallContractRequestMethodName,
StxCallContractRequestParams
>;

// Result
export const stxCallContractResponseBodySchema = stacksTransactionDetailsSchema;

export type StxCallContractResponse = RpcResponse<typeof stxCallContractResponseBodySchema>;

export type DefineStxCallContractMethod = DefineRpcMethod<
StxCallContractRequest,
StxCallContractResponse
>;
32 changes: 32 additions & 0 deletions packages/rpc/src/methods/stacks/stx-deploy-contract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from 'zod';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';
import { stacksTransactionDetailsSchema } from './_stacks-helpers';

export const stxDeployContractMethodName = 'stx_deployContract';

type StxDeployContractRequestMethodName = typeof stxDeployContractMethodName;

// Request
export const stxDeployContractRequestParamsSchema = z.object({
name: z.string(),
clarityCode: z.string(),
clarityVersion: z.coerce.number().optional(),
});

export type StxDeployContractRequestParams = z.infer<typeof stxDeployContractRequestParamsSchema>;

export type StxDeployContractRequest = RpcRequest<
StxDeployContractRequestMethodName,
StxDeployContractRequestParams
>;

// Result
export const stxDeployContractResponseBodySchema = stacksTransactionDetailsSchema;

export type StxDeployContractResponse = RpcResponse<typeof stxDeployContractResponseBodySchema>;

export type DefineStxDeployContractMethod = DefineRpcMethod<
StxDeployContractRequest,
StxDeployContractResponse
>;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefineRpcMethod, RpcParameterByName, RpcRequest, RpcResponse } from '../rpc/schemas';
import { DefineRpcMethod, RpcParameterByName, RpcRequest, RpcResponse } from '../../rpc/schemas';

export const stxMessageSigningTypes = ['utf8', 'structured'] as const;

Expand Down
46 changes: 46 additions & 0 deletions packages/rpc/src/methods/stacks/stx-sign-transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { z } from 'zod';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';

export const stxSignTransactionMethodName = 'stx_signTransaction';

// Leather's RPC params prior to SIP-30
// Developers should be warned away from this structure
export const stxSignTransactionRequestLeatherRpcParamsSchema = z.object({
txHex: z.string(),
stxAddress: z.string().optional(),
attachment: z.string().optional(),
accountIndex: z.string().optional(),
});

// SIP-30 params
export const stxSignTransactionRequestSip30ParamsSchema = z.object({ transaction: z.string() });

export const stxSignTransactionRequestParamsSchema = z.union([
stxSignTransactionRequestLeatherRpcParamsSchema,
stxSignTransactionRequestSip30ParamsSchema,
]);

export type StxSignTransactionRequestParams = z.infer<
typeof stxSignTransactionRequestSip30ParamsSchema
>;

// For backwards compatibility, we return the same data under both properties
export const stxSignTransactionResponseSchema = z.object({
transaction: z.string(),
txHex: z.string(),
});

export type StxSignTransactionResponseBody = z.infer<typeof stxSignTransactionResponseSchema>;

export type StxSignTransactionRequest = RpcRequest<
typeof stxSignTransactionMethodName,
StxSignTransactionRequestParams
>;

export type StxSignTransactionResponse = RpcResponse<StxSignTransactionResponseBody>;

export type DefineStxSignTransactionMethod = DefineRpcMethod<
StxSignTransactionRequest,
StxSignTransactionResponse
>;
32 changes: 32 additions & 0 deletions packages/rpc/src/methods/stacks/stx-transfer-sip10-ft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from 'zod';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';
import { stacksTransactionDetailsSchema } from './_stacks-helpers';

export const stxTransferSip10FtMethodName = 'stx_transferSip10Ft';

type StxTransferSip10FtRequestMethodName = typeof stxTransferSip10FtMethodName;

// Request
export const stxTransferSip10FtRequestParamsSchema = z.object({
recipient: z.string(),
asset: z.string(),
amount: z.coerce.number(),
});

export type StxTransferSip10FtRequestParams = z.infer<typeof stxTransferSip10FtRequestParamsSchema>;

export type StxTransferSip10FtRequest = RpcRequest<
StxTransferSip10FtRequestMethodName,
StxTransferSip10FtRequestParams
>;

// Result
export const stxTransferSip10FtResponseBodySchema = stacksTransactionDetailsSchema;

export type StxTransferSip10FtResponse = RpcResponse<typeof stxTransferSip10FtResponseBodySchema>;

export type DefineStxTransferSip10FtMethod = DefineRpcMethod<
StxTransferSip10FtRequest,
StxTransferSip10FtResponse
>;
32 changes: 32 additions & 0 deletions packages/rpc/src/methods/stacks/stx-transfer-stx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from 'zod';

import { DefineRpcMethod, RpcRequest, RpcResponse } from '../../rpc/schemas';
import { stacksTransactionDetailsSchema } from './_stacks-helpers';

export const stxTransferStxMethodName = 'stx_transferStx';

type StxTransferStxRequestMethodName = typeof stxTransferStxMethodName;

// Request
export const stxTransferStxRequestParamsSchema = z.object({
recipient: z.string(),
amount: z.number(),
memo: z.string().optional(),
});

export type StxTransferStxRequestParams = z.infer<typeof stxTransferStxRequestParamsSchema>;

export type StxTransferStxRequest = RpcRequest<
StxTransferStxRequestMethodName,
StxTransferStxRequestParams
>;

// Result
export const stxTransferStxResponseBodySchema = stacksTransactionDetailsSchema;

export type StxTransferStxResponse = RpcResponse<typeof stxTransferStxResponseBodySchema>;

export type DefineStxTransferStxMethod = DefineRpcMethod<
StxTransferStxRequest,
StxTransferStxResponse
>;
Loading

0 comments on commit 46af901

Please sign in to comment.