2025-12-24

野蛮生长

前段时间看了下Coinbase的API想着写点东西.

想着多少是涉及钱的东西,所以想着看看能不能不用SDK.
毕竟感觉上,本身就不是个什么特别正规的行业,而且盯着的人也多,供应链上难说没有什么问题.

粗略翻了下文档,倒也不算写得不好.
除去SDK之外,还是有标准的Http JWT形式的提供的.

就是跟国内某些云厂商的文档一样,类别分类只能你懂了之后才懂怎么找.

稍微看了下jwt的签名方式,然后再对了下文档,感觉中间缺了一大段.
估计也没想着有人会直接从头写.

于是估计省事,ChatGTP和Gemini vibe了一下.
让no external dependency地写个client和一些简单策略描述帮助测试,还有就是让预留扩展interface以方便拔插.

gpt绕来绕去还是用上了sdk.

gemini倒是挺直接出了个纯typescript builtin function的版本.
不够提示jwt签名算法不对的时候,又绕回到jose这个jwt库了.

反向情绪价值了几轮,倒是给写了个像模像样的版本.
而且让给写test case mock api看着也挺一回事的.

然后review了下感觉client的部分略复杂.
签名的部分看着也不大对劲.

于是就放弃了.
转回古法编程.

当然,私心也是不够顺手太啰嗦.
顺便还能看看jwt的四种写法.

然后开始翻RFC.

抽象层面倒是挺简单.
然后回去对照了下文档,发觉少了签名的部分.

于是仔细翻了翻.
发觉文档的jwt其实指的是jwk+jws.
即一种json结构描述的key信息,和对应的key的signature的算法.
然后以json/jwt的方式encode一下.

继续翻了翻文档和几个RFC,发觉都是语焉不详的.

文档大部分术语表达其实是按照jose这个high level的jwt库来描述的.
而RFC里有大部分都是optional字段.

一时也没办法知道具体哪些是必要的,哪些是可选的.

现在想想,这个也算暗示了后面Coinbase API一些有趣的地方.

比如像jwt RFC里以及像老一点的oauth等签名方式里,都会要求有一个nouce去防止重放的.
甚至在jwt中,除了这类时间因素外,jwt还有一些从SSL CA方面借鉴过来的东西.

像除了nouce之外,还能assign一个unique id给每个jwt,以及限定token的有效时间区间.
还有就是issuer和subject这类概念.
加上key算法可以是非对称的方式.

所以形式上来说,安全模型算是挺标准完备的.

但关键这些都是optional的.

而且实际上coinbase的实现里,其实也就主要校验了key产生的签名.
像上面说的重放策略什么的,实际是可以重放的.

所以理论上来说,如果它的API Gateway没有做什么特别工程的话,是有可能重复或者意外retry的.
比如多买或者多卖,甚至多转帐理论上应该都是可能发生的.

当然,要说本来就套了一层Https/SSL了,没必要也不是说不过去.

但多多少少算是做的并不太符合预期.

毕竟作为一个怎么说也是金融交易系统的API,校验完全依赖底层通信协议,业务甚至API层面本身没有校验逻辑的话,也多少又些让人意外.

不过,说完全没有校验倒也不至于.
只不过逻辑很奇怪.

因为它会校验请求的url/api路径.

也就是说,在它的jwt的header部分会要求有个uris参数.
这个参数基本就是固定的api path.

如果缺少这个参数加入到签名过程,这个签名是401的.

对于相当一部分API来说,这个基本就是个常量.
所以,对于这部分API来说,这个必要参数显得也不是那么必要.

毕竟对安全性并没有提升.
而且形式上还增加的请求的大小.
也就是无效信息也多了.

想了想有价值的可能是某些url里面带某类动态id的可能会有意义.
比如针对某个transaction的操作之类的,可能会有一个标识嵌入到API路径上.

但这也解决不了产生这些标识的API的安全性问题.

另外就是这种放着标准的防重放机制不用,利用这么一个类似oauth api scope的字段去做随机化的事情,多少有点让人费解.

当然,这些可能知识trade api的问题.
其他类别的可能另一套底层处理机制的话,可能没这些问题.

但是,作为比较核心的交易API的话,多多少少是有些让人不太舒服的.

毕竟这种情况下,一旦遇到中间人,基本上就属于裸奔状态了.
因为即使不知道密钥,但是从请求上是可以看出操作类型的.

比如只是一毛钱的转帐/交易测试,理论上也可以通过重放去扩大的.

联系诸如perceptual这类衍生品的交易概念,交易所形式上来说其实又挺多合理的操作空间的.

比如你的margin可能不是cross的,只是针对某一个产品,也加了止损止盈线.
但是吧,可重放和重试之间模糊的界限,理论上和形式上是可以放大不利场景的.

而且因为虽然API Gateway后面并不校验nouce,但是SDK层面又注入.
所以你要证明是过错方也是有点缺乏依据的.

即使不在交易上出问题,在转账上面也是有可能有一些利润空间的.

像perceptual的funding payment概念.

形式上来说,这个是根据所谓的为了衍生品跟底层标的挂钩平衡加入的激励因素.
比如标的是BTC,然后对应的衍生品BTC perceptual会给予call/sell方以动态的正负利息/税费收入.

根据交易所自己的平衡原则,你call BTC perceptual可能会有一定利息,或者要付一定利息.
sell侧也是.

而且这个东西每小时结算一次.
极端产品的这个小时利息是可能倒万分之一的.

在这种情况下去重放,即使市场本身不波动,交易所那边也还是有可能有超额收益的.

当然,有funding payment这种东西的存在,交易所也犯不着去搞那么复杂的重发了.

毕竟税率既定,而且实际流水的变动相较于市场的波动,可能一般人也不会注意到,或者说在意.

而如果跟进一步考虑的话,这个可能就更有意思了.

因为它的结算单位是USDC.
所以宏观上里说,每小时是有一定市场持仓比例的USDC以这个费率的形式作为交易所收入固化回去的.

而交易苏的所有交易其实都是机遇USDC或者其他所谓稳定币维系的.

因为虽然你可以cash in和cash out各种法币.
但是你其实并不难直接用法币交易非stable coin.

或者说,有路径,但是一般也不会通过非stable coin的方式进行转化.

于是从会计角度来说,形式上,交易所账上的USDC负债会比例性地转换为资产.

再假设,如果交易所有自己的类stable coin的代币.
那么完全可以用这部分转化的资产去对自己的代币进行市值管理.

同时因为市值正向增长,而且属于自我发行的一般代币.
再基于代币进行市场融资进一步放大杠杆,然后回头做市也是有可能的.

所以总的来说,这套东西还是挺野蛮的.








野蛮生长

前段时间看了下Coinbase的API想着写点东西. 想着多少是涉及钱的东西,所以想着看看能不能不用SDK. 毕竟感觉上,本身就不是个什么特别正规的行业,而且盯着的人也多,供应链上难说没有什么问题. 粗略翻了下文档,倒也不算写得不好. 除去SDK之外,还是有标准的Http JWT...