import { Address, ArrayItemType, isAddressObject } from './utils'; /* Account stuff */ /** * @category Models */ export interface ContractState { balance: string; genTimings: GenTimings; lastTransactionId?: LastTransactionId; isDeployed: boolean; codeHash?: string; } /** * @category Models */ export interface FullContractState { boc: string; balance: string; genTimings: GenTimings; lastTransactionId?: LastTransactionId; isDeployed: boolean; codeHash?: string; } /** * @category Models */ export type GenTimings = { genLt: string; genUtime: number; }; /** * @category Models */ export type ContractUpdatesSubscription = { /** * Whether to listen contract state updates */ state: boolean; /** * Whether to listen new contract transactions */ transactions: boolean; }; /** * @category Models */ export type TransactionsBatchInfo = { minLt: string; maxLt: string; batchType: TransactionsBatchType; }; /** * @category Models */ export type TransactionsBatchType = 'old' | 'new'; /** * @category Models */ export type Transaction = { id: TransactionId; prevTransactionId?: TransactionId; createdAt: number; aborted: boolean; exitCode?: number; resultCode?: number; origStatus: AccountStatus; endStatus: AccountStatus; totalFees: string; inMessage: Message; outMessages: Message[]; }; /** * @category Models */ export type TransactionWithAccount = Transaction & { account: Addr }; /** * @category Models */ export type RawTransaction = Transaction; /** * @category Models */ export function serializeTransaction(transaction: Transaction): RawTransaction { // NOTE: deep copy to prevent sending objects with prototypes through the channel return { id: { hash: transaction.id.hash, lt: transaction.id.lt, }, prevTransactionId: transaction.prevTransactionId != null ? { hash: transaction.prevTransactionId.hash, lt: transaction.prevTransactionId.lt, } : undefined, createdAt: transaction.createdAt, aborted: transaction.aborted, exitCode: transaction.exitCode, resultCode: transaction.resultCode, origStatus: transaction.origStatus, endStatus: transaction.endStatus, totalFees: transaction.totalFees, inMessage: serializeMessage(transaction.inMessage), outMessages: transaction.outMessages.map(serializeMessage), }; } /** * @category Models */ export function parseTransaction(transaction: RawTransaction): Transaction { return { ...transaction, inMessage: parseMessage(transaction.inMessage), outMessages: transaction.outMessages.map(parseMessage), }; } /** * @category Models */ export type Message = { hash: string; src?: Addr; dst?: Addr; value: string; bounce: boolean; bounced: boolean; body?: string; bodyHash?: string; }; /** * @category Models */ export type RawMessage = Message; /** * @category Models */ export function serializeMessage(message: Message): RawMessage { // NOTE: deep copy to prevent sending objects with prototypes through the channel return { hash: message.hash, src: message.src ? message.src.toString() : undefined, dst: message.dst ? message.dst.toString() : undefined, value: message.value, bounce: message.bounce, bounced: message.bounced, body: message.body, bodyHash: message.bodyHash, }; } /** * @category Models */ export function parseMessage(message: RawMessage): Message { return { ...message, src: message.src ? new Address(message.src) : undefined, dst: message.dst ? new Address(message.dst) : undefined, }; } /** * @category Models */ export type DelayedMessage = { /** * External message hash */ hash: string; /** * Destination account address (`sender` for `sendMessageDelayed`, `recipient` for `sendExternalMessageDelayed`) */ account: Addr; /** * Message expiration timestamp */ expireAt: number; }; /** * @category Models */ export type AccountStatus = 'uninit' | 'frozen' | 'active' | 'nonexist'; /** * @category Models */ export type LastTransactionId = { isExact: boolean; lt: string; hash?: string; }; /** * @category Models */ export type TransactionId = { lt: string; hash: string; }; /* Permissions stuff */ /** * @category Models */ export type Permissions = { basic: true; accountInteraction: { address: Addr; publicKey: string; contractType: string; }; }; /** * @category Models */ export type RawPermissions = Permissions; /** * @category Models */ export function parsePermissions(permissions: Partial): Partial { return { ...permissions, accountInteraction: permissions.accountInteraction ? parseAccountInteraction(permissions.accountInteraction) : undefined, }; } /** * @category Models */ export function parseAccountInteraction( accountInteraction: Required['accountInteraction'], ): Required['accountInteraction'] { return { ...accountInteraction, address: new Address(accountInteraction.address), }; } /** * @category Models */ export type Permission = keyof Permissions; /** * @category Models */ export type PermissionData = Permissions[T]; /* Assets stuff */ /** * @category Models */ export type AssetType = 'tip3_token'; /** * @category Models */ export type AssetTypeParams = T extends 'tip3_token' ? { rootContract: Addr; } : never; /** * @category Models */ export type EncryptionAlgorithm = 'ChaCha20Poly1305'; /** * @category Models */ export type EncryptedData = { algorithm: EncryptionAlgorithm; /** * Hex encoded encryptor's public key */ sourcePublicKey: string; /** * Hex encoded recipient public key */ recipientPublicKey: string; /** * Base64 encoded data */ data: string; /** * Base64 encoded nonce */ nonce: string; }; /* Network stuff */ /** * @category Models */ export type NetworkDescription = { globalId: number; capabilities: string; signatureId: number | undefined; signatureContext: SignatureContext; }; /** * @category Models */ export type SignatureContext = | { type: 'empty' } // ton/legacy networks | { type: 'signatureId'; globalId: number } // simple prefix | { type: 'signatureDomainL2'; globalId: number }; // full domain prefix /** * @category Models */ export type NetworkConfig = { symbol?: string; decimals?: number; explorerBaseUrl?: string; tokensManifestUrl?: string; }; /** * @category Models */ export type GqlSocketParams = { /** * Path to graphql api endpoints */ endpoints: string[]; /** * Frequency of sync latency detection */ latencyDetectionInterval: number; /** * Maximum value for the endpoint's blockchain data sync latency */ maxLatency: number; /** * Gql node type */ local: boolean; }; /** * @category Models */ export type JrpcSocketParams = { /** * Path to jrpc api endpoint */ endpoint: string; }; /** * @category Models */ export type ProtoSocketParams = JrpcSocketParams & {}; export type GqlConnection = { type: 'graphql'; data: GqlSocketParams }; export type JrpcConnection = { type: 'jrpc'; data: JrpcSocketParams }; export type ProtoConnection = { type: 'proto'; data: ProtoSocketParams }; /** * @category Models */ export type Network = { name: string; description: NetworkDescription; connection: GqlConnection | JrpcConnection | ProtoConnection | any; config: NetworkConfig; }; /** * @category Models */ export type AddNetwork = { name: string; networkId: number; connection: GqlConnection | JrpcConnection | ProtoConnection | any; config?: NetworkConfig; }; /** * @category Models */ export type IgnoreTransactionTreeSimulationError = { /** * Contract address. * If not specified, the error will be ignored for all contracts. */ address?: Addr; /** * Error code to be ignored */ code: number; }; /* ABI stuff */ /** * @category Models */ export type AbiVersion = '1.0' | '2.0' | '2.1' | '2.2' | '2.3'; /** * @category Models */ // NOTE: `boolean` must be after `string` due to JS being itself - https://github.com/vuejs/core/issues/9253 export type TokenValue = | null | string | number | Addr | boolean | { [K in string]: TokenValue } | TokenValue[] | (readonly [TokenValue, TokenValue])[]; /** * @category Models */ export type RawTokenValue = TokenValue; /** * @category Models */ export type TokensObject = { [K in string]: TokenValue }; /** * @category Models */ export type RawTokensObject = TokensObject; /** * @category Models */ export type FunctionCall = { /** * Contract ABI */ abi: string; /** * Specific method from specified contract ABI */ method: string; /** * Method arguments */ params: TokensObject; }; /** * @category Models */ export type GetterCall = { /** * Contract ABI */ abi: string; /** * Specific getter from specified contract ABI */ getter: string; /** * Getter arguments */ params: TokensObject; }; type AbiParamKindUint = 'uint8' | 'uint16' | 'uint24' | 'uint32' | 'uint64' | 'uint128' | 'uint160' | 'uint256'; type AbiParamKindInt = 'int8' | 'int16' | 'int24' | 'int32' | 'int64' | 'int128' | 'int160' | 'int256'; type AbiParamKindVarUint = 'varuint16' | 'varuint32'; type AbiParamKindVarInt = 'varint16' | 'varint32'; type AbiParamKindTuple = 'tuple'; type AbiParamKindBool = 'bool'; type AbiParamKindCell = 'cell'; type AbiParamKindAddress = 'address'; type AbiParamKindBytes = 'bytes'; type AbiParamKindFixedBytes = `fixedbytes${NonZeroDigit | `${'1' | '2'}${Digit}` | '30' | '31' | '32'}`; type AbiParamKindString = 'string'; type AbiParamKindGram = 'gram'; type AbiParamKindTime = 'time'; type AbiParamKindExpire = 'expire'; type AbiParamKindPublicKey = 'pubkey'; type AbiParamKindArray = `${AbiParamKind}[]`; type AbiParamKindMapKey = AbiParamKindInt | AbiParamKindUint | AbiParamKindAddress; type AbiParamKindMap = `map(${AbiParamKindMapKey},${AbiParamKind | `${AbiParamKind}[]`})`; type AbiParamOptional = `optional(${AbiParamKind})`; type AbiParamRef = `ref(${AbiParamKind})`; type AbiParamOptionalRef = `optional(ref(${AbiParamKind}))`; type AbiParamRefOptional = `ref(optional(${AbiParamKind}))`; type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; type NonZeroDigit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; /** * @category Models */ export type AbiParamKind = | AbiParamKindUint | AbiParamKindInt | AbiParamKindVarUint | AbiParamKindVarInt | AbiParamKindTuple | AbiParamKindBool | AbiParamKindCell | AbiParamKindAddress | AbiParamKindBytes | AbiParamKindFixedBytes | AbiParamKindString | AbiParamKindGram | AbiParamKindTime | AbiParamKindExpire | AbiParamKindPublicKey; /** * @category Models */ export type AbiParam = { name: string; type: | AbiParamKind | AbiParamKindMap | AbiParamKindArray | AbiParamOptional | AbiParamRef | AbiParamOptionalRef | AbiParamRefOptional; components?: AbiParam[]; }; /** * @category Models */ export type ReadonlyAbiParam = { name: string; type: | AbiParamKind | AbiParamKindMap | AbiParamKindArray | AbiParamOptional | AbiParamRef | AbiParamOptionalRef | AbiParamRefOptional; components?: readonly ReadonlyAbiParam[]; }; /** * @category Models */ export function serializeTokensObject(object: TokensObject): RawTokensObject { return serializeTokenValue(object as TokenValue) as RawTokensObject; } function serializeTokenValue(token: TokenValue): RawTokenValue { if (typeof token === 'object' && isAddressObject(token)) { return token!.toString(); } if (Array.isArray(token)) { const result: RawTokenValue[] = []; for (const item of token as TokenValue[]) { result.push(serializeTokenValue(item)); } return result; } else if (token != null && typeof token === 'object') { const result: { [name: string]: RawTokenValue } = {}; for (const [key, value] of Object.entries(token)) { result[key] = serializeTokenValue(value); } return result; } else { return token; } } /** * @category Models */ export function serializeIgnoreCode( object: IgnoreTransactionTreeSimulationError, ): IgnoreTransactionTreeSimulationError { return { address: object.address?.toString(), code: object.code }; } /** * @category Models */ export function parseTokensObject(params: AbiParam[], object: RawTokensObject): TokensObject { const result: TokensObject = {}; for (const param of params) { result[param.name] = parseTokenValue(param, object[param.name]); } return result; } /** * @category Models */ export function parsePartialTokensObject(params: AbiParam[], object: Partial): TokensObject { const result: TokensObject = {}; for (const param of params) { if (Object.prototype.hasOwnProperty.call(object, param.name)) { result[param.name] = parseTokenValue(param, !object[param.name]); } } return result; } function parseTokenValue(param: AbiParam, token: RawTokenValue): TokenValue { if (!param.type.startsWith('map')) { const isArray = param.type.endsWith('[]'); const isOptional = !isArray && param.type.startsWith('optional'); const rawType = ( isArray ? param.type.slice(0, -2) : isOptional ? param.type.slice(9, -1) : param.type ) as AbiParamKind; if (isArray) { const rawParam = { name: param.name, type: rawType, components: param.components } as AbiParam; const result: TokenValue[] = []; for (const item of token as TokenValue[]) { result.push(parseTokenValue(rawParam, item)); } return result; } else if (isOptional) { if (token == null) { return null; } else { const rawParam = { name: param.name, type: rawType, components: param.components } as AbiParam; return parseTokenValue(rawParam, token); } } else if (rawType === 'tuple') { type TokenValueTuple = { [K in string]: TokenValue }; const result: TokenValueTuple
= {}; if (param.components != null) { for (const component of param.components) { result[component.name] = parseTokenValue(component, (token as TokenValueTuple)[component.name]); } } return result; } else if (rawType === 'address') { return new Address(token as string) as TokenValue; } else { return token; } } else { type TokenValueMap = (readonly [TokenValue, TokenValue])[]; const valueTypeIndex = param.type.indexOf(','); const keyType = param.type.slice(4, valueTypeIndex); const valueType = param.type.slice(valueTypeIndex + 1, -1); const result: TokenValueMap
= []; for (const [key, value] of token as unknown as TokenValueMap) { result.push([ parseTokenValue( { name: '', type: keyType as AbiParamKind, }, key, ), parseTokenValue( { name: '', type: valueType as AbiParamKind, components: param.components, }, value, ), ]); } return result; } } // prettier-ignore type InputTokenValue = T extends AbiParamKindUint | AbiParamKindInt | AbiParamKindVarUint | AbiParamKindVarInt | AbiParamKindGram | AbiParamKindTime | AbiParamKindExpire ? string | number : T extends AbiParamKindBool ? boolean : T extends AbiParamKindCell | AbiParamKindBytes | AbiParamKindFixedBytes | AbiParamKindString | AbiParamKindPublicKey ? string : T extends AbiParamKindAddress ? Address : T extends AbiParamKindTuple ? MergeInputObjectsArray : T extends `${infer K}[]` ? InputTokenValue[] : T extends `map(${infer K},${infer V})` ? (readonly [InputTokenValue, InputTokenValue])[] : T extends `optional(${infer V})` | `ref(optional(${infer V}))` | `optional(ref(${infer V}))` ? (InputTokenValue | null) : T extends `ref(${infer V})` ? InputTokenValue : never; // prettier-ignore type OutputTokenValue = T extends AbiParamKindUint | AbiParamKindInt | AbiParamKindVarUint | AbiParamKindVarInt | AbiParamKindGram | AbiParamKindTime | AbiParamKindCell | AbiParamKindBytes | AbiParamKindFixedBytes | AbiParamKindString | AbiParamKindPublicKey ? string : T extends AbiParamKindExpire ? number : T extends AbiParamKindBool ? boolean : T extends AbiParamKindAddress ? Address : T extends AbiParamKindTuple ? MergeOutputObjectsArray : T extends `${infer K}[]` ? OutputTokenValue[] : T extends `map(${infer K},${infer V})` ? (readonly [OutputTokenValue, OutputTokenValue])[] : T extends `optional(${infer V})` | `ref(optional(${infer V}))` | `optional(ref(${infer V}))` ? (OutputTokenValue | null) : T extends `ref(${infer V})` ? OutputTokenValue : never; /** * @category Models */ export type InputTokenObject = O extends { name: infer K; type: infer T; components?: infer C } ? K extends string ? { [P in K]: InputTokenValue } : never : never; /** * @category Models */ export type OutputTokenObject = O extends { name: infer K; type: infer T; components?: infer C } ? K extends string ? { [P in K]: OutputTokenValue } : never : never; /** * @category Models */ export type MergeInputObjectsArray = A extends readonly [infer T, ...infer Ts] ? InputTokenObject & MergeInputObjectsArray<[...Ts]> : A extends readonly [infer T] ? InputTokenObject : A extends readonly [] ? {} : never; /** * @category Models */ export type MergeOutputObjectsArray = A extends readonly [infer T, ...infer Ts] ? OutputTokenObject & MergeOutputObjectsArray<[...Ts]> : A extends readonly [infer T] ? OutputTokenObject : A extends readonly [] ? {} : never; /** * @category Models */ export type AbiFunctions = C extends { functions: infer F } ? F extends readonly unknown[] ? ArrayItemType : never : never; /** * @category Models */ export type AbiGetters = C extends { getters: infer F } ? F extends readonly unknown[] ? ArrayItemType : never : never; /** * @category Models */ export type AbiEvents = C extends { events: infer E } ? E extends readonly unknown[] ? ArrayItemType : never : never; /** * @category Models */ export type AbiFields = C extends { fields: infer F } ? F : never; /** * @category Models */ export type AbiFunction> = Extract, { name: T }>; /** * @category Models */ export type AbiGetter> = Extract, { name: T }>; /** * @category Models */ export type AbiEvent> = Extract, { name: T }>; /** * @category Models */ export type AbiFunctionName = AbiFunctions['name']; /** * @category Models */ export type AbiGetterName = AbiGetters['name']; /** * @category Models */ export type AbiEventName = AbiEvents['name']; /** * @category Models */ export type AbiFieldName = keyof DecodedAbiFields; /** * @category Models */ export type AbiFunctionInputs> = MergeInputObjectsArray['inputs']>; /** * @category Models */ export type AbiFunctionInputsWithDefault> = AbiFunction< C, T >['inputs'] extends readonly [] ? void | Record : AbiFunctionInputs; /** * @category Models */ export type DecodedAbiFunctionInputs> = MergeOutputObjectsArray< AbiFunction['inputs'] >; /** * @category Models */ export type DecodedAbiFunctionOutputs> = MergeOutputObjectsArray< AbiFunction['outputs'] >; /** * @category Models */ export type AbiGetterInputs> = MergeInputObjectsArray['inputs']>; /** * @category Models */ export type AbiGetterInputsWithDefault> = AbiGetter['inputs'] extends readonly [] ? void | Record : AbiGetterInputs; /** * @category Models */ export type DecodedAbiGetterInputs> = MergeOutputObjectsArray['inputs']>; /** * @category Models */ export type DecodedAbiGetterOutputs> = MergeOutputObjectsArray< AbiGetter['outputs'] >; /** * @category Models */ export type DecodedAbiEventData> = MergeOutputObjectsArray['inputs']>; /** * @category Models */ export type DecodedAbiInitData = C extends { data: infer D } ? Partial> : never; /** * @category Models */ export type DecodedAbiFields = C extends { fields: infer F } ? MergeOutputObjectsArray : never;